<?php
namespace Assetic\Filter;
use Assetic\Asset\AssetInterface;
use Assetic\Exception\FilterException;
use Symfony\Component\Process\ProcessBuilder;
class SprocketsFilter implements FilterInterface {
private $sprocketsLib;
private $rubyBin;
private $includeDirs;
private $assetRoot;
public function __construct($sprocketsLib = null, $rubyBin = '/usr/bin/ruby') {
$this->sprocketsLib = $sprocketsLib;
$this->rubyBin = $rubyBin;
$this->includeDirs = array();
}
public function addIncludeDir($directory) {
$this->includeDirs[] = $directory;
}
public function setAssetRoot($assetRoot) {
$this->assetRoot = $assetRoot;
}
public function filterLoad(AssetInterface $asset) {
static $format = <<<'EOF'
#!/usr/bin/env ruby
require %s
%s
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;
$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, $this->sprocketsLib ? sprintf('File.join(%s, \'sprockets\')', var_export($this->sprocketsLib, true)) : '\'sprockets\'', $this
->getHack($asset), var_export($tmpAsset, true), $more));
$pb = new ProcessBuilder(array(
$this->rubyBin,
$input,
));
$proc = $pb
->getProcess();
$code = $proc
->run();
unlink($tmpAsset);
unlink($input);
if (0 < $code) {
throw FilterException::fromProcess($proc)
->setInput($asset
->getContent());
}
$asset
->setContent($proc
->getOutput());
}
public function filterDump(AssetInterface $asset) {
}
private function getHack(AssetInterface $asset) {
static $format = <<<'EOF'
module Sprockets
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
EOF;
$root = $asset
->getSourceRoot();
$path = $asset
->getSourcePath();
if ($root && $path) {
return sprintf($format, var_export(dirname($root . '/' . $path), true));
}
}
}