Take a look at @import in less-files for getting lastModified #151

rejinka opened this Issue Jan 8, 2013 · 3 comments

3 participants


Following situation: I include a bootstrap.less, which looks like

@import "variables.less"
@import "layout.less"

If i change anything in variables.less or layout.less, the assetic controller won't regenerate the css file, because the only lastModified, which is interesting for it, is the one of bootstrap.less. As you see, it can be interesting to look on the lastModified property of other files, too.

So i wrote some code, to get the wished behavior:


namespace UPB\NuctahCoreBundle\Util\Assetic;

use \Symfony\Bundle\AsseticBundle\Factory\AssetFactory as BaseAssetFactory;

use \UPB\NuctahCoreBundle\Util\Assetic\Asset\LessFileAsset;

class AssetFactory extends BaseAssetFactory
    protected function createFileAsset($source, $root = null, $path = null, $vars)
        if (preg_match('/\.less$/', $source))
            return new LessFileAsset($source, array(), $root, $path, $vars);

        return parent::createFileAsset($source, $root, $path, $vars);



namespace UPB\NuctahCoreBundle\Util\Assetic\Asset;

use \Assetic\Asset\FileAsset;

use \NajiDev\Common\Helper\StringHelper;

class LessFileAsset extends FileAsset
    public function getLastModified()
        // this is our regular expression for finding import statements.
        $importExpression = '/@import "(.*)";/';

        $filesToDo = array();
        $filesDone = array();

        $filesToDo[] = $this->getSourceRoot() . '/' . $this->getSourcePath();
        while (!empty($filesToDo))
            $filename = array_pop($filesToDo);
            $filename = realpath($filename);

            // if we handled this file, jump to next one
            if (in_array($filename, $filesDone))

            // fetch all import statements
            if (preg_match_all($importExpression, file_get_contents($filename), $matches))
                foreach ($matches[1] as $file)
                    // cut a possible ".less" and add it again
                    // possible: @import "variables" and @import "variables.less"
                    $file =   StringHelper::trimStringRight($file, '.less') . '.less';

                    if (false !== $file = realpath(dirname($filename) . '/' . $file))
                        $filesToDo[] = $file;

            $filesDone[] = $filename;

        $lastModified = 0;
        foreach ($filesDone as $file)
            if ($lastModified < $newLastModified = filemtime($file))
                $lastModified = $newLastModified;

        return $lastModified;

Another class, which i used in LessFileAsset:


namespace NajiDev\Common\Helper;

use \NajiDev\Common\Exception\InvalidArgumentException;

class StringHelper
      * Strip a string from the end of a string
      * @param string $str      the input string
      * @param string $remove   string to remove
      * @throws \NajiDev\Common\Exception\InvalidArgumentException
      * @return string the modified string
    public static function trimStringRight($str, $remove)
        if (!is_string($str))
            throw new InvalidArgumentException('$str has to be a string');

        if (!is_string($remove))
            throw new InvalidArgumentException('$remove has to be a string');

        $len    = strlen($remove);
        $offset = strlen($str) - $len;

        while(0 < $offset && strpos($str, $remove, $offset) === $offset)
            $str    = substr($str, 0, $offset);
            $offset = strlen($str)-$len;

        return $str;

If you have any suggestions for modifing my code, please let me know. I would then create a pull request (and also modify the code to match your code guideline)

Symfony member

Having some stuff specific to less in the asset factory does not make sense (the asset factory should not be responsible for it, and the issue is not limited to less).

Please see kriswallsmith/assetic#79 where the discussion about the issue happens


@stof This bug is still open - does that mean the problem has still not been fixed? kriswallsmith/assetic#79 doesn't mention if the less filter specifically has been fixed, it just lays the groundwork so it could be. Is there another bug to track the less filter (apart from this one)?

What is the recommended workaround?

Symfony member

the Lessfilter implements getChildren in the latest dev version of assetic

@stof stof closed this Oct 4, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment