public function filterLoad(AssetInterface $asset)
    {
        $sourceUrl = $asset->getSourceUrl();
        if (!$sourceUrl || false !== strpos($sourceUrl, '://')) {
            return;
        }

        $options = array($this->sprocketizePath);

        foreach ($this->includeDirs as $directory) {
            $options[] = '-I';
            $options[] = $directory;
        }

        if (null !== $this->assetRoot) {
            $options[] = '-a';
            $options[] = $this->assetRoot;
        }

        // hack in a temporary file sibling
        $options[] = $input = dirname($this->baseDir.'/'.$sourceUrl).'/.'.rand(11111, 99999).'-'.basename($sourceUrl);
        $tmp = tempnam(sys_get_temp_dir(), 'assetic_sprockets');
        file_put_contents($tmp, $asset->getContent());
        rename($tmp, $input);

        $proc = new Process(implode(' ', array_map('escapeshellarg', $options)));
        $code = $proc->run();
        unlink($input);

        if (0 < $code) {
            throw new \RuntimeException($proc->getErrorOutput());
        }

        $asset->setContent($proc->getOutput());
    }
Example #2
0
 public function filterDump(AssetInterface $asset)
 {
     $sourceUrl = $asset->getSourceUrl();
     $targetUrl = $asset->getTargetUrl();
     if (null === $sourceUrl || null === $targetUrl || $sourceUrl == $targetUrl) {
         return;
     }
     // learn how to get from the target back to the source
     if (false !== strpos($sourceUrl, '://')) {
         // the source is absolute, this should be easy
         $parts = parse_url($sourceUrl);
         $host = $parts['scheme'] . '://' . $parts['host'];
         $path = dirname($parts['path']) . '/';
     } else {
         // assume source and target are on the same host
         $host = '';
         // pop entries off the target until it fits in the source
         if ('.' == dirname($sourceUrl)) {
             $path = str_repeat('../', substr_count($targetUrl, '/'));
         } elseif ('.' == ($targetDir = dirname($targetUrl))) {
             $path = dirname($sourceUrl) . '/';
         } else {
             $path = '';
             while (0 !== strpos($sourceUrl, $targetDir)) {
                 if (false !== ($pos = strrpos($targetDir, '/'))) {
                     $targetDir = substr($targetDir, 0, $pos);
                     $path .= '../';
                 } else {
                     $targetDir = '';
                     $path .= '../';
                     break;
                 }
             }
             $path .= substr(dirname($sourceUrl) . '/', strlen($targetDir) + 1);
         }
     }
     $callback = function ($matches) use($host, $path) {
         if (false !== strpos($matches['url'], '://')) {
             // absolute
             return $matches[0];
         }
         if ('/' == $matches['url'][0]) {
             // root relative
             return str_replace($matches['url'], $host . $matches['url'], $matches[0]);
         }
         // document relative
         $url = $matches['url'];
         while (0 === strpos($url, '../') && 2 <= substr_count($path, '/')) {
             $path = substr($path, 0, strrpos(rtrim($path, '/'), '/') + 1);
             $url = substr($url, 3);
         }
         return str_replace($matches['url'], $host . $path . $url, $matches[0]);
     };
     $content = $asset->getContent();
     $content = preg_replace_callback('/url\\((["\']?)(?<url>.*)(\\1)\\)/', $callback, $content);
     $content = preg_replace_callback('/import (["\'])(?<url>.*)(\\1)/', $callback, $content);
     $asset->setContent($content);
 }
Example #3
0
 public function filterLoad(AssetInterface $asset)
 {
     $sourceUrl = $asset->getSourceUrl();
     if ($sourceUrl && false === strpos($sourceUrl, '://')) {
         $baseDir = self::isAbsolutePath($sourceUrl) ? '' : $this->baseDir . '/';
         $sourceUrl = $baseDir . $sourceUrl;
     }
     $lc = new \lessc($sourceUrl);
     // the way lessc::parse is implemented, the content wins if both url and content are defined
     $asset->setContent($lc->parse($asset->getContent()));
 }
Example #4
0
    public function filterLoad(AssetInterface $asset)
    {
        static $format = <<<'EOF'
var less = require('less');
var sys  = require('sys');

new(less.Parser)(%s).parse(%s, function(e, tree) {
    if (e) {
        less.writeError(e);
        process.exit(2);
    }

    try {
        sys.print(tree.toCSS(%s));
        process.exit(0);
    } catch (e) {
        less.writeError(e);
        process.exit(3);
    }
});

EOF;
        $sourceUrl = $asset->getSourceUrl();
        // parser options
        $parserOptions = array();
        if ($sourceUrl && false === strpos($sourceUrl, '://')) {
            $baseDir = self::isAbsolutePath($sourceUrl) ? '' : $this->baseDir . '/';
            $parserOptions['paths'] = array($baseDir . dirname($sourceUrl));
            $parserOptions['filename'] = basename($sourceUrl);
        }
        // tree options
        $treeOptions = array();
        if (null !== $this->compress) {
            $treeOptions['compress'] = $this->compress;
        }
        // node.js configuration
        $env = array();
        if (0 < count($this->nodePaths)) {
            $env['NODE_PATH'] = implode(':', $this->nodePaths);
        }
        $options = array($this->nodeBin);
        $options[] = $input = tempnam(sys_get_temp_dir(), 'assetic_less');
        file_put_contents($input, sprintf($format, json_encode($parserOptions), json_encode($asset->getContent()), json_encode($treeOptions)));
        $proc = new Process(implode(' ', array_map('escapeshellarg', $options)), null, $env);
        $code = $proc->run();
        unlink($input);
        if (0 < $code) {
            throw new \RuntimeException($proc->getErrorOutput());
        }
        $asset->setContent($proc->getOutput());
    }
Example #5
0
    /**
     * {@inheritdoc}
     */
    public function filterLoad(AssetInterface $asset)
    {
        static $format = <<<JAVASCRIPT
var stylus = require('stylus'),
       sys = require('sys');

stylus(%s, %s).render(function(e, css){
    if (e) {
        throw e;
    }

    sys.print(css);
    process.exit(0);
});

JAVASCRIPT;

        // parser options
        $parserOptions = array();
        if ($sourceUrl = $asset->getSourceUrl()) {
            $parserOptions['filename']  = basename($sourceUrl);
            $parserOptions['paths']     = array($this->baseDir . DIRECTORY_SEPARATOR . dirname($sourceUrl));
        }

        if (null !== $this->compress) {
            $parserOptions['compress'] = $this->compress;
        }

        // node.js configuration
        $env = array();
        if (0 < count($this->nodePaths)) {
            $env['NODE_PATH'] = implode(':', $this->nodePaths);
        }

        $options = array($this->nodeBin);
        $options[] = $input = tempnam(sys_get_temp_dir(), 'assetic_stylus');
        file_put_contents($input, sprintf($format,
            json_encode($asset->getContent()),
            json_encode($parserOptions)
        ));

        $proc = new Process(implode(' ', array_map('escapeshellarg', $options)), null, $env);
        $code = $proc->run();
        unlink($input);

        if (0 < $code) {
            throw new \RuntimeException($proc->getErrorOutput());
        }

        $asset->setContent($proc->getOutput());
    }
Example #6
0
 public function filterDump(AssetInterface $asset)
 {
     $filters = $this->filters;
     $plugins = $this->plugins;
     if (isset($filters['ImportImports']) && true === $filters['ImportImports']) {
         // find the base path
         $sourceUrl = $asset->getSourceUrl();
         if (self::isAbsoluteUrl($sourceUrl) || self::isAbsolutePath($sourceUrl)) {
             $filters['ImportImports'] = array('BasePath' => dirname($sourceUrl));
         } elseif ($this->baseDir) {
             $filters['ImportImports'] = array('BasePath' => $this->baseDir);
             if ('.' != ($dir = dirname($sourceUrl))) {
                 $filters['ImportImports']['BasePath'] .= '/' . $dir;
             }
         }
     }
     $asset->setContent(\CssMin::minify($asset->getContent(), $filters, $plugins));
 }
    public function filterDump(AssetInterface $asset)
    {
        $sourceUrl = $asset->getSourceUrl();
        $targetUrl = $asset->getTargetUrl();

        if (null === $sourceUrl || null === $targetUrl || $sourceUrl == $targetUrl) {
            return;
        }

        // learn how to get from the target back to the source
        if (false !== strpos($sourceUrl, '://')) {
            // the source is absolute, this should be easy
            $parts = parse_url($sourceUrl);

            $host = $parts['scheme'].'://'.$parts['host'];
            $path = dirname($parts['path']).'/';
        } else {
            // assume source and target are on the same host
            $host = '';

            // pop entries off the target until it fits in the source
            $path = '';
            $targetDir = dirname($targetUrl);
            while (0 !== strpos($sourceUrl, $targetDir)) {
                if (false !== $pos = strrpos($targetDir, '/')) {
                    $targetDir = substr($targetDir, 0, $pos);
                    $path .= '../';
                } else {
                    throw new \RuntimeException(sprintf('Unable to calculate relative path from "%s" to "%s"', $targetUrl, $sourceUrl));
                }
            }
            $path .= substr(dirname($sourceUrl).'/', strlen($targetDir) + 1);
        }

        $filter = function($url) use($host, $path)
        {
            if (false !== strpos($url, '://')) {
                // absolute
                return $url;
            } elseif ('/' == $url[0]) {
                // root relative
                return $host.$url;
            } else {
                // document relative
                while (0 === strpos($url, '../') && 2 <= substr_count($path, '/')) {
                    $path = substr($path, 0, strrpos(rtrim($path, '/'), '/') + 1);
                    $url = substr($url, 3);
                }
                return $host.$path.$url;
            }
        };

        // tokenize and filter the asset content
        $tokens = $this->tokenizer->tokenizeString($asset->getContent());

        // cleanup the php tags codesniffer adds
        $tokens = array_slice($tokens, 1, -1);
        $token = array_pop($tokens);
        if (' ' != $token['content']) {
            $token['content'] = substr($token['content'], 0, -1);
            $tokens[] = $token;
        }

        $content = '';
        $inUrl = $inImport = 0;
        for ($i = 0; $i < count($tokens); $i++) {
            $token = $tokens[$i];

            if (T_URL == $token['code']) {
                $token['content'] = $filter($token['content']);
            } elseif (T_STRING == $token['code'] && 'url' == $token['content']) {
                $inUrl = 1;
            } elseif (T_STRING == $token['code'] && 'import' == $token['content'] && isset($tokens[$i - 1]) && T_ASPERAND == $tokens[$i - 1]['code']) {
                $inImport = 1;
            } elseif (T_OPEN_PARENTHESIS == $token['code'] && 1 == $inUrl) {
                $inUrl = 2;
            } elseif (T_CONSTANT_ENCAPSED_STRING == $token['code'] && (2 == $inUrl || 1 == $inImport)) {
                $quote = $token['content'][0];
                $url = $filter(substr($token['content'], 1, -1));
                $token['content'] = $quote.$url.$quote;
            } elseif (T_WHITESPACE != $token['code']) {
                $inUrl = $inImport = 0;
            }

            $content .= $token['content'];
        }

        $asset->setContent($content);
    }
Example #8
0
    /**
     * Hack around a bit, get the job done.
     */
    public function filterLoad(AssetInterface $asset)
    {
        static $format = <<<'EOF'
#!/usr/bin/env ruby

require File.join(%s, 'sprockets')

module Sprockets
  class Secretary
    def reset!(options = @options)
      @options = DEFAULT_OPTIONS.merge(options)
      @environment  = Sprockets::Environment.new(@options[:root])
      @preprocessor = Sprockets::Preprocessor.new(@environment, :strip_comments => @options[:strip_comments])

      add_load_locations(@options[:load_path])
      add_source_files(@options[:source_files])
    end
  end

  class Preprocessor
    protected

    def pathname_for_relative_require_from(source_line)
      Sprockets::Pathname.new(@environment, File.join(%s, location_from(source_line)))
    end
  end
end

options = { :load_path    => [],
            :source_files => [%s],
            :expand_paths => false }

%ssecretary = Sprockets::Secretary.new(options)
secretary.install_assets if options[:asset_root]
print secretary.concatenation

EOF;
        $sourceUrl = $asset->getSourceUrl();
        if (!$sourceUrl || false !== strpos($sourceUrl, '://')) {
            return;
        }
        $more = '';
        foreach ($this->includeDirs as $directory) {
            $more .= 'options[:load_path] << ' . var_export($directory, true) . "\n";
        }
        if (null !== $this->assetRoot) {
            $more .= 'options[:asset_root] = ' . var_export($this->assetRoot, true) . "\n";
        }
        if ($more) {
            $more .= "\n";
        }
        $tmpAsset = tempnam(sys_get_temp_dir(), 'assetic_sprockets');
        file_put_contents($tmpAsset, $asset->getContent());
        $input = tempnam(sys_get_temp_dir(), 'assetic_sprockets');
        file_put_contents($input, sprintf($format, var_export($this->sprocketsLib, true), var_export($this->baseDir, true), var_export($tmpAsset, true), $more));
        $proc = new Process($cmd = implode(' ', array_map('escapeshellarg', array($this->rubyBin, $input))));
        $code = $proc->run();
        unlink($tmpAsset);
        unlink($input);
        if (0 < $code) {
            throw new \RuntimeException($proc->getErrorOutput());
        }
        $asset->setContent($proc->getOutput());
    }