MatthiasMullie\Minify\CSS::move PHP Method

move() protected method

Relative references (e.g. ../images/image.gif) in a certain css file, will have to be updated when a file is being saved at another location (e.g. ../../images/image.gif, if the new CSS file is 1 folder deeper).
protected move ( MatthiasMullie\PathConverter\Converter $converter, string $content ) : string
$converter MatthiasMullie\PathConverter\Converter Relative path converter
$content string The CSS content to update relative urls for
return string
    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;
    }