1

I am compressing multiple CSS files in to one and moving new generated css file to own folder. The move messes up the images, @import and fonts paths.

Can someone take a look at this and see if you can manage to fix the path for the following.

$content ='
    @import url(comments.css);<br />
    @import url(../comments.css);<br />
    @import url(../../comments.css);<br />
    background:url(http://example.com/test.jpg);<br />
    background:url("http://example.com/test.jpg");<br />
    background:url( "//example.com/test.jpg" );<br />
    background:url(//example.com/test.jpg);<br />
    background:url(test.jpg);<br />
    background:url(images/test.jpg);<br />
    background:url(../images/test.jpg);<br />
    background:url(../../images/test.jpg);<br />
    background:url(../../../images/test.jpg);<br />
    background:url(../../../images/test.jpg);<br />
  ';

$content .="
    background:url('http://example.com/test.jpg');<br />
    background:url('../images/test.jpg'  );<br />
";

$path = 'http://www.some.com/cached';
$re = "/url\\(\\s*[\\'\"]?\\/?(.+?)[\\'\"]?\\s*\\)/i"; 
$content = preg_replace($re, 'url('.$path.'/$1)', $content);

echo $content ;

Example http://sandbox.onlinephpfunctions.com/code/20668872e49ea96b57964a9ee7176a5bbd796a5c

The desired outcome would be this

@import url(http://www.some.com/cached/comments.css);
@import url(http://www.some.com/cached/comments.css);
@import url(http://www.some.com/cached/comments.css);
background:url(http://example.com/test.jpg);
background:url(http://example.com/test.jpg);
background:url(//example.com/test.jpg);
background:url(//example.com/test.jpg);
background:url(http://www.some.com/cached/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://example.com/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);

Any help is appreciated.

7
  • since its a one off job, i would just do it by hand Commented Nov 18, 2014 at 23:05
  • @Dagon what makes you think that this is one off job? I said I am using multiple files and cant go trough each to make changes for imports , images or fonts. Commented Nov 18, 2014 at 23:10
  • @Dagon what is the matter with you? I gave an example so that anyone can test. If you dont want to help, dont comment Commented Nov 18, 2014 at 23:20
  • 1
    if you don't want comments don't post in a public forum. Do you really want to process the file on every page load just to change the urls rather than changing them just once? Commented Nov 18, 2014 at 23:23
  • @Dagon, you really need to read before you comment, how is my question different from all the ones that want CSS urls changed via php? And who said I will process a file on every page load? I am looking for a regex to do what I need. The file is cached and used if it is there but that was not even a question. So I do not see any reason for you to blur around about things that I was not even asking about. Down voting my question just because you think that I should do something that I did not ask about is plain childish. Commented Nov 18, 2014 at 23:28

2 Answers 2

2

This does everything you wanted.

<?php
    // The content (heredoc syntax is cleaner when dealing with large strings)
    $content = <<<EOT
@import url(comments.css);<br />
@import url(../comments.css);<br />
@import url(../../comments.css);<br />
background:url(http://example.com/test.jpg);<br />
background:url("http://example.com/test.jpg");<br />
background:url( "//example.com/test.jpg" );<br />
background:url(//example.com/test.jpg);<br />
background:url(test.jpg);<br />
background:url(images/test.jpg);<br />
background:url(../images/test.jpg);<br />
background:url(../../images/test.jpg);<br />
background:url(../../../images/test.jpg);<br />
background:url(../../../images/test.jpg);<br />'
background:url('http://example.com/test.jpg');<br />
background:url('../images/test.jpg'  );<br />
EOT;

    // Set path
    $path = 'http://www.some.com/cached/';

    // Clear out the line breaks
    $content = str_replace('<br />', '', $content);

    // Clear out bogus whitespace
    $content = preg_replace('/\(\s+/', '(', $content);
    $content = preg_replace('/\s+\)/', ')', $content);

    // Clear out quotes
    $content = preg_replace('/(?:\'|\")/', '', $content);

    // Replaces repeating ../ patterns
    $content = preg_replace('/(?:\.\.\/)+(.*?\))/', $path.'$1', $content);

    // Prepend the path to lines that do not have a "//" anywhere
    $content = preg_replace('/(url\((?!.*\/\/))/i', '$1'.$path, $content);

    echo $content;

I corrected these 2 lines in from desired outcome:

background:url(/http://example.com/test.jpg);
background:url(/http://example.com/test.jpg);
Sign up to request clarification or add additional context in comments.

2 Comments

thank you for the line by line explanation. does much more than what I asked for.
Your code is amazing, just one problem though. I have some other css with this as well, and it takes out quotes from all other css properties. Is there anyway it takes out quotes from urls only?
2

Well Dagon is thinking ahead while OP just wants to do what was asked so I understand both points. If OP knows what they want and believe it is the best solution then I'll accommodate, though Dagon makes valid points.

The below ought to work for you, but may not account for everything contortion. I'd remove the example.com lines just to make processing it easier and not have to account for every possibility with one regex, but that's me:

$content ='
    @import url(comments.css);<br />
    @import url(../comments.css);<br />
    @import url(../../comments.css);<br />
    background:url(http://example.com/test.jpg);<br />
    background:url("http://example.com/test.jpg");<br />
    background:url( "//example.com/test.jpg" );<br />
    background:url(//example.com/test.jpg);<br />
    background:url(test.jpg);<br />
    background:url(images/test.jpg);<br />
    background:url(../images/test.jpg);<br />
    background:url(../../images/test.jpg);<br />
    background:url(../../../images/test.jpg);<br />
    background:url(../../../images/test.jpg);<br />
  ';

$content .="
    background:url('http://example.com/test.jpg');<br />
    background:url('../images/test.jpg'  );<br />
";

// contains example.com stuff
$matches1 = preg_replace($r1, '', $content);
// contains everything that does not contain example.com
$matches2 = preg_replace($r2, '', $content);

// replace relative paths
$output = preg_replace('~\((?:[./\s\'"]+|)~', '(http://www.some.com/cached/', $matches2);
// replace example.com stuff
$output .= preg_replace('~(?<!http:)//~', 'http://', $matches1);

print_r($output,false);

Outputs the following

@import url(http://www.some.com/cached/comments.css);
@import url(http://www.some.com/cached/comments.css);
@import url(http://www.some.com/cached/comments.css);
background:url(http://www.some.com/cached/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg);
background:url(http://www.some.com/cached/images/test.jpg' );
background:url(http://example.com/test.jpg);
background:url("http://example.com/test.jpg");
background:url( "http://example.com/test.jpg" );
background:url(http://example.com/test.jpg);
background:url('http://example.com/test.jpg');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.