class IPF_Assets
{
private $files = array();
+ private $dirs = array();
- public static function compile($dir, $path)
+ public function __construct($dir)
{
- $compiler = new IPF_Assets;
+ $this->dirs = array(
+ rtrim($dir, '/'),
+ IPF::get('project_root') . '/vendor/bower-asset',
+ );
+ }
- $root = self::joinPath($dir, $path);
- list($success, $data) = \PFF\TopSort::sort(array($root), array($compiler, 'following'));
+ public function compileFile($path)
+ {
+ $root = $this->path($path);
+ list($success, $data) = \PFF\TopSort::sort(array($root), array($this, 'following'));
if (!$success)
throw new Exception('Loop detected: '.implode(' -> ', $data));
$dump = array();
foreach ($data as $path) {
- $dump[] = $compiler->files[$path];
+ $dump[] = $this->files[$path];
}
return implode("\n", $dump);
}
+ public static function compile($dir, $path)
+ {
+ $compiler = new IPF_Assets($dir);
+ return $compiler->compileFile($path);
+ }
+
function following($path)
{
if (!array_key_exists($path, $this->files))
if (!preg_match_all('#^(//=\\s*require\\s*(\\S+)|/\\*=\\s*require\\s*(\\S+)\\s*\\*/)\\s*$#m', $content, $matches, PREG_SET_ORDER))
return array();
- $dir = dirname($path);
+ $currentDir = dirname($path);
+
$result = array();
foreach ($matches as $m) {
- $result[] = self::joinPath($dir, @$m[2].@$m[3]);
+ $result[] = $this->path(@$m[2].@$m[3], $currentDir);
}
return $result;
}
- private static function joinPath($base, $file)
+ private function possiblePaths($file, $currentDir=null)
{
- if (mb_substr($file, 0, 1) === '/')
- $path = realpath($file);
- else
- $path = realpath($base . '/' . $file);
+ $file = ltrim($file, '/');
+ $paths = array();
+
+ if ($currentDir)
+ $paths[] = rtrim($currentDir, '/') . '/' . $file;
- if (!$path)
- throw new Exception("File '$file' not found in '$base'.");
+ foreach ($this->dirs as $base)
+ $paths[] = $base . '/' . $file;
- return $path;
+ return $paths;
+ }
+
+ function path($file, $currentDir=null)
+ {
+ $paths = array_filter(array_map('realpath', $this->possiblePaths($file, $currentDir)));
+ if (!$paths)
+ throw new Exception("File '$file' not found in '" . implode("', '", $this->dirs) . "'.");
+ return array_shift($paths);
}
}
IPF_Utils::copyDirectory($source, $destination);
foreach ($app->assets() as $asset => $output) {
- $content = IPF_Assets::compile($app->getPath(), $asset);
+ $compiler = new IPF_Assets($app->getPath());
+ $src = $compiler->path($asset);
$dest = $destination . $output;
- IPF_Utils::makeDirectories(dirname($dest));
- file_put_contents($dest, $content);
+
+ if (is_dir($src)) {
+ IPF_Utils::copyDirectory($src, $dest);
+ } else {
+ $content = $compiler->compileFile($asset);
+ IPF_Utils::makeDirectories(dirname($dest));
+ file_put_contents($dest, $content);
+ }
}
}
}