public function Emogrifier::emogrify in HTML Mail 5
Same name and namespace in other branches
- 6 emogrifier/emogrifier.php \Emogrifier::emogrify()
File
- emogrifier/
emogrifier.php, line 69 - CSS to Inline Converter Class
Class
Code
public function emogrify() {
$body = $this->html;
// process the CSS here, turning the CSS style blocks into inline css
if (count($this->unprocessableHTMLTags)) {
$unprocessableHTMLTags = implode('|', $this->unprocessableHTMLTags);
$body = preg_replace("/<({$unprocessableHTMLTags})[^>]*>/i", '', $body);
}
$xmldoc = new DOMDocument();
$xmldoc->strictErrorChecking = false;
$xmldoc->formatOutput = true;
$xmldoc
->loadHTML($body);
$xmldoc
->normalizeDocument();
$xpath = new DOMXPath($xmldoc);
// get rid of css comment code
$re_commentCSS = '/\\/\\*.*\\*\\//sU';
$css = preg_replace($re_commentCSS, '', $this->css);
// process the CSS file for selectors and definitions
$re_CSS = '/^\\s*([^{]+){([^}]+)}/mis';
preg_match_all($re_CSS, $css, $matches);
foreach ($matches[1] as $key => $selectorString) {
// if there is a blank definition, skip
if (!strlen(trim($matches[2][$key]))) {
continue;
}
// split up the selector
$selectors = explode(',', $selectorString);
foreach ($selectors as $selector) {
// don't process pseudo-classes
if (strpos($selector, ':') !== false) {
continue;
}
// query the body for the xpath selector
$nodes = $xpath
->query($this
->translateCSStoXpath(trim($selector)));
foreach ($nodes as $node) {
// if it has a style attribute, get it, process it, and append (overwrite) new stuff
if ($node
->hasAttribute('style')) {
$style = $node
->getAttribute('style');
// break it up into an associative array
$oldStyleArr = $this
->cssStyleDefinitionToArray($node
->getAttribute('style'));
$newStyleArr = $this
->cssStyleDefinitionToArray($matches[2][$key]);
// new styles overwrite the old styles (not technically accurate, but close enough)
$combinedArr = array_merge($oldStyleArr, $newStyleArr);
$style = '';
foreach ($combinedArr as $k => $v) {
$style .= $k . ':' . $v . ';';
}
}
else {
// otherwise create a new style
$style = trim($matches[2][$key]);
}
$node
->setAttribute('style', $style);
}
}
}
// This removes styles from your email that contain display:none;. You could comment these out if you want.
$nodes = $xpath
->query('//*[contains(translate(@style," ",""),"display:none;")]');
foreach ($nodes as $node) {
$node->parentNode
->removeChild($node);
}
return $xmldoc
->saveHTML();
}