/** * Imports the file * * @param string $path The path to import. Path will be searched by the importers * @param bool $tryAppendLessExtension Whether to try appending the less extension (if the path has no extension) * @param array $importOptions Import options * @param integer $index Current index * @return array * @throws ImportException If the $path could not be imported */ public function import($path, $tryAppendLessExtension = false, FileInfo $currentFileInfo, array $importOptions = [], $index = 0) { $plugin = isset($importOptions['plugin']) && $importOptions['plugin']; $inline = isset($importOptions['inline']) && $importOptions['inline']; $css = isset($importOptions['css']) && $importOptions['css']; if ($tryAppendLessExtension && !pathinfo($path, PATHINFO_EXTENSION)) { if ($plugin) { $path .= '.php'; } else { $path .= '.less'; } } // we must generate separate cache for inline and css files to avoid problems // when someone wants to import the less file first as inline import and than normally $cacheKey = $this->generateCacheKey((Util::isPathAbsolute($path) ? $path : $currentFileInfo->currentDirectory . $path) . 'css-' . (int) $inline . 'inline-' . (int) $css); // do we have a file in the cache? if ($this->cache->has($cacheKey)) { // check the modified timestamp $file = $this->cache->get($cacheKey); // search foreach ($this->importers as $importer) { /* @var $file ImportedFile */ /* @var $importer ImporterInterface */ $lastModified = $importer->getLastModified($path, $currentFileInfo); if ($lastModified !== false && $lastModified === $file->getLastModified()) { // the modification time is the same, take the one from cache return $this->doImport($file, $path, $currentFileInfo, $importOptions, true); } } } foreach ($this->importers as $importer) { /* @var $importer ImporterInterface */ $file = $importer->import($path, $currentFileInfo); // import is handled by the importer if ($file instanceof ImportedFile) { if ($plugin) { // create dummy ruleset which will hold the functions $ruleset = new RulesetNode([], []); $ruleset->root = false; $ruleset->functions[] = $file->getPath(); $file->setRuleset($ruleset); return [true, $file]; } else { $result = $this->doImport($file, $path, $currentFileInfo, $importOptions); /* @var $file ImportedFile */ list(, $file) = $result; // save the cache $this->cache->set($cacheKey, $file); return $result; } } } throw new ImportException(sprintf("'%s' wasn't found.", $path), $index, $currentFileInfo); }
/** * Converts the ruleset to CSS. Applies the output filters to the output. * * @param RulesetNode $ruleset * @param array $variables * * @return string The generated CSS code */ protected function toCSS(RulesetNode $ruleset, array $variables) { // the cache key consists of: // 1) parsed rules // 2) assigned variables via the API // 3) environment options $cacheKey = $this->generateCacheKey(serialize($this->rules) . serialize($variables) . serialize([$this->context->compress, $this->context->sourceMap, $this->context->sourceMapOptions, $this->context->relativeUrls, $this->context->numPrecision, $this->context->dumpLineNumbers, $this->context->canShortenColors, $this->context->ieCompat, $this->context->strictMath, $this->context->strictUnits, $this->context->urlArgs, $this->context->dumpLineNumbers, $this->context->strictImports])); $rebuild = true; $css = null; if ($this->cache->has($cacheKey)) { $rebuild = false; list($css, $importedFiles) = $this->cache->get($cacheKey); // we need to check if the file has been modified foreach ($importedFiles as $importedFileArray) { list($lastModifiedBefore, $path, $currentFileInfo) = $importedFileArray; $lastModified = $this->importer->getLastModified($path, $currentFileInfo); if ($lastModifiedBefore != $lastModified) { $rebuild = true; // no need to continue, we will rebuild the CSS break; } } } if ($rebuild) { $css = parent::toCSS($ruleset, $variables); // what have been imported? $importedFiles = []; foreach ($this->importer->getImportedFiles() as $importedFile) { // we need to save original path, last modified timestamp and currentFileInfo object // see ILess\Importer::setImportedFile() $importedFiles[] = [$importedFile[0]->getLastModified(), $importedFile[1], $importedFile[2]]; } $this->cache->set($cacheKey, [$css, $importedFiles]); } return $this->filter($css); }