Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I've problem with sending HTML mails with PHPMailer. I make a Smarty template and I got all the HTML code from it. But when I send mail, I got the mail without included CSS (it's only background-color, font or something like that). In PHPMailer I set that the mail is HTML.

Is there any way to send HTML mail with included CSS?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
534 views
Welcome To Ask or Share your Answers For Others

1 Answer

There's is a way...

    $body = <<< YOUR_HTML_WITH_CSS_STYLE_TAGS
<html>
<head>
    <style>
        body * {width:1px;}
        #adiv {padding:2px;}
        .aclass {margin:3px;}
    </style>
</head>
<body>
    <div>
        some html
    </div>
    <div id="adiv">
        <p class="aclass">
        </p>
    </div>
</body>
</html>
YOUR_HTML_WITH_CSS_STYLE_TAGS;
    $doc = new DOMDocument();
    @$doc->loadHTML($body);
    $xpd = new DOMXPath($doc);
    0&&$node = new DOMElement();
    $result = $xpd->query('//img');
    foreach($result as $node){
        $attr = $node->getAttribute('src');
        $re = '/(http://.*?)?(/.*+)/i';
        if(preg_match_all($re, $attr, $matches)){
            if(!empty($matches[1][0])&&0)
                continue;
            $attr = 'http://'.$_SERVER['HTTP_HOST'].$matches[2][0];
        }
        $node->setAttribute('src',$attr);
    }
    false&&$node=new DOMElement()&&$child=new DOMElement();
    $result = $xpd->query('//style/..');
    foreach($result as $node){
        foreach($node->childNodes as $child){
            if(strtolower($child->nodeName)=='style'){
                $node->removeChild($child);
                $css = $child->textContent;
                $re = '/(.*?){([^}]+)}/';
                if(preg_match_all($re, $css, $matches)){
                    foreach($matches[1] as $idx=>$css_selector){
                        $css_text = $matches[2][$idx];
                        $css_text = preg_replace('/s+/',' ',$css_text);
                        $css = new CSSQuery($doc);
                        foreach($css->query($css_selector) as $selected_node){
                            $style = $selected_node->getAttribute('style');
                            $selected_node->setAttribute('style', $style?$css_text:$style.';'.$css_text);
                        }
                    }
                }
            }
        }
    }
    $body = $doc->saveHTML();

That code will generate an HTML output in $body like this:

<html>
<head>
</head>
<body>
    <div style="width:1px;">
        some html
    </div>
    <div id="adiv" style="width:1px;padding:2px;">
        <p class="aclass" style="width:1px;margin:3px;">
        </p>
    </div>
</body>
</html>

The CSSQuery class can be found at phpclasses.org. This implementation is based on the fact that most webmails will only allow to add style by an inline tag attribute style and not through style tags or link tags.

It's pretty much limited and with a restricted syntax because of the regular expression it's kind of simple, but it's still better than write by your own the inline style attributes in each HTML tag.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...