protected function move(Converter $converter, $content)
{
/*
* Relative path references will usually be enclosed by url(). @import
* is an exception, where url() is not necessary around the path (but is
* allowed).
* This *could* be 1 regular expression, where both regular expressions
* in this array are on different sides of a |. But we're using named
* patterns in both regexes, the same name on both regexes. This is only
* possible with a (?J) modifier, but that only works after a fairly
* recent PCRE version. That's why I'm doing 2 separate regular
* expressions & combining the matches after executing of both.
*/
$relativeRegexes = array('/
# open url()
url\\(
\\s*
# open path enclosure
(?P<quotes>["\'])?
# fetch path
(?P<path>
# do not fetch data uris or external sources
(?!(
\\s?
["\']?
(data|https?):
))
.+?
)
# close path enclosure
(?(quotes)(?P=quotes))
\\s*
# close url()
\\)
/ix', '/
# import statement
@import
# whitespace
\\s+
# we don\'t have to check for @import url(), because the
# condition above will already catch these
# open path enclosure
(?P<quotes>["\'])
# fetch path
(?P<path>
# do not fetch data uris or external sources
(?!(
["\']?
(data|https?):
))
.+?
)
# close path enclosure
(?P=quotes)
/ix');
// find all relative urls in css
$matches = array();
foreach ($relativeRegexes as $relativeRegex) {
if (preg_match_all($relativeRegex, $content, $regexMatches, PREG_SET_ORDER)) {
$matches = array_merge($matches, $regexMatches);
}
}
$search = array();
$replace = array();
// loop all urls
foreach ($matches as $match) {
// determine if it's a url() or an @import match
$type = strpos($match[0], '@import') === 0 ? 'import' : 'url';
// attempting to interpret GET-params makes no sense, so let's discard them for awhile
$params = strrchr($match['path'], '?');
$url = $params ? substr($match['path'], 0, -strlen($params)) : $match['path'];
// fix relative url
$url = $converter->convert($url);
// now that the path has been converted, re-apply GET-params
$url .= $params;
// build replacement
$search[] = $match[0];
if ($type == 'url') {
$replace[] = 'url(' . $url . ')';
} elseif ($type == 'import') {
$replace[] = '@import "' . $url . '"';
}
}
// replace urls
$content = str_replace($search, $replace, $content);
return $content;
}