Skip to content

Instantly share code, notes, and snippets.

@wpottier
Created September 5, 2012 09:18
Show Gist options
  • Save wpottier/3633935 to your computer and use it in GitHub Desktop.
Save wpottier/3633935 to your computer and use it in GitHub Desktop.
Symfony2CssRewriteFilter
<?php
namespace Clever\Presenter\CoreBundle\Assetic\Filter;
use Assetic\Filter\BaseCssFilter;
use Assetic\Asset\AssetInterface;
/**
* Fixes relative CSS urls.
* Support of Symfony relative bundles url
*
* @author Kris Wallsmith <kris.wallsmith@gmail.com>
* @author William POTTIER <wpottier@allprogrammic.com>
*/
class Symfony2CssRewriteFilter extends BaseCssFilter
{
public function filterLoad(AssetInterface $asset)
{
}
public function filterDump(AssetInterface $asset)
{
$sourceBase = $asset->getSourceRoot();
$sourcePath = $asset->getSourcePath();
$targetPath = $asset->getTargetPath();
if (null === $sourcePath || null === $targetPath || $sourcePath == $targetPath) {
return;
}
// learn how to get from the target back to the source
if (false !== strpos($sourceBase, '://')) {
list($scheme, $url) = explode('://', $sourceBase.'/'.$sourcePath, 2);
list($host, $path) = explode('/', $url, 2);
$host = $scheme.'://'.$host.'/';
$path = false === strpos($path, '/') ? '' : dirname($path);
$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($sourcePath)) {
$path = str_repeat('../', substr_count($targetPath, '/'));
} elseif ('.' == $targetDir = dirname($targetPath)) {
$path = dirname($sourcePath).'/';
} else {
$path = '';
while (0 !== strpos($sourcePath, $targetDir)) {
if (false !== $pos = strrpos($targetDir, '/')) {
$targetDir = substr($targetDir, 0, $pos);
$path .= '../';
} else {
$targetDir = '';
$path .= '../';
break;
}
}
$path .= ltrim(substr(dirname($sourcePath).'/', strlen($targetDir)), '/');
}
}
$content = $this->filterReferences($asset->getContent(), function($matches) use($host, $path, $sourceBase, $sourcePath)
{
if (false !== strpos($matches['url'], '://') || 0 === strpos($matches['url'], '//') || 0 === strpos($matches['url'], 'data:')) {
// absolute or protocol-relative or data uri
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);
}
$result = str_replace($matches['url'], $host.$path.$url, $matches[0]);
// Symfony Bundle
if(strpos($sourceBase, 'Bundle') !== false && strpos($sourcePath, 'Resources/') === 0) {
preg_match('/(src|vendor)\/([a-zA-Z\/]+)Bundle/', $sourceBase, $bundleMatches);
$bundleName = strtolower(str_replace('/', '', $bundleMatches[2]));
preg_match('/Resources\/([a-zA-Z]+)\//', $sourcePath, $pathMatches);
$result = str_replace('Resources/'.$pathMatches[1], sprintf('bundles/%s', $bundleName), $result);
}
return $result;
});
$asset->setContent($content);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment