1

I've been using regex to wrap my images in < a > tags and altering their paths etc. I know using dom for this is better, having read a lot of threads about wrapping, but I'm unable to understand how to.

This is what I'm using:

$comments = (preg_replace('@(<img.+src=[\'"]/uploads/userdirs/admin)(?:.*?/)(.+?)\.(.+?)([\'"].*?>)@i', '<a class="gallery" rel="'.$pagelink.'" href=/uploads/userdirs/'.$who.'/$2.$3>$1/mcith/mcith_$2.$3$4</a>', $comments));

It successfully wraps each image in the tags I want. But only if the string provided ($comments) has the right markup.

<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /></p>
<p><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>

When presented like this, it works. I'm using tinymce so it wraps in < p > when I do a linebreak with enter. But when I don't do that, when I just insert images one after another so the HTML looks like this, it won't:

<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>

It will instead wrap those 2 images in the same < a > tag. Making the output look like this:

<p><a class="gallery" rel="test" href="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg">
<img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960">
<img src="/uploads/userdirs/admin/mcith/mcith_100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024">
</a></p>

Which is wrong. The output I want is this:

<p><a class="gallery" rel="test2" href="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg"><img src="/uploads/userdirs/admin/mcith/mcith_100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024"></a></p>
<p><a class="gallery" rel="test2" href="/uploads/userdirs/admin/1154686260226.jpg"><img src="/uploads/userdirs/admin/mcith/mcith_1154686260226.jpg" alt="" width="1280" height="800"></a></p>
2
  • 1
    If you don't understand how to do it the right way, then you should probably ask how to do it the right way, not get into a conversation on how to get the wrong way working. Commented Apr 26, 2012 at 9:36
  • i am doing that though. either way works for me.. if anyone can push me in the right direction toward a dom rewrite, i would be very happy =) Commented Apr 26, 2012 at 9:40

2 Answers 2

2

I've left out a few details, but here's how I would do it using DOMDocument:

$s = <<<EOM
<p><img src="/uploads/userdirs/admin/1160501362291.png" alt="" width="1280" height="960" /></p>
<p><img src="/uploads/userdirs/admin/100_Bullets_68_1280x1024.jpg" alt="" width="1280" height="1024" /></p>
EOM;

$d = new DOMDocument;
$d->loadHTML($s);

foreach ($d->getElementsByTagName('img') as $img) {
    $img_src = $img->attributes->getNamedItem('src')->nodeValue;
    if (0 === strncasecmp($img_src, '/uploads/userdirs/admin', 23)) {
        $a = $d->createElement('a');

        $a->setAttribute('class', 'gallery');
        $a->setAttribute('rel', 'whatever');
        $a->setAttribute('href', '/uploads/userdirs/username/' . $img_src);

        // disconnect image tag from parent
        $img->parentNode->replaceChild($a, $img);

        // and move to anchor
        $a->appendChild($img);
    }
}

echo $d->saveHTML();
Sign up to request clarification or add additional context in comments.

3 Comments

thank you so much! that is helping me a whole lot! it works, rewrites no matter what i throw at it. trying to pull the filename out of it so i can do : $a->setAttribute('href', '/uploads/userdirs/username/thumbnail/' . $img_filename); Can domdocument do that?
I've declared a variable $img_src inside the loop that contains the value of the original image location. Is that what you need?
yup! im using pathinfo now to yoink just the filename =) Thank you so much for helping me understand domdocument.
1

You should change .* in your regular expression with [^>]*. The latter means: any character expect than >. Because regular expression gets as long match as possible. Without this additional condition, this ends up with two <img>'s matched.

3 Comments

hmm, like this? $comments = (preg_replace('@(<img.+src=[\'"]/uploads/userdirs/admin)(?:[^>]*.?/)(.+?)\.(.+?)([\'"][^>]*.?>)@i', '<a class="gallery" rel="'.$pagelink.'" href=/uploads/userdirs/'.$who.'/$2.$3>$1/mcith/mcith_$2.$3$4</a>', $comments)); i'm getting the same output using that.
Adding also some [^"] and for + specifier helps: @(<img[^>]+src=['"]/uploads/userdirs/admin)(?:[^"]*?/)([^"]+?).([^"]+?)(['"][^>]*?>)@i
But as there was said, using some HTML parser as DOM would be much more safer.

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.