浏览代码

Make emogrifier work

euromark 11 年之前
父节点
当前提交
93726e10e0

+ 46 - 28
Lib/InlineCssLib.php

@@ -17,37 +17,44 @@ class InlineCssLib {
 
 	const ENGINE_EMOGRIFIER = 'emogrifier';
 
+	/**
+	 * Default config
+	 *
+	 * @var array
+	 */
 	protected $_defaults = array(
 		'engine' => self::ENGINE_CSS_TO_INLINE,
 		'cleanup' => true,
 		'useInlineStylesBlock' => true,
-		'xhtmlOutput' => false,
-		'removeCss' => true,
-		'debug' => false,
-		'correctUtf8' => false
+		'debug' => false, // only cssToInline
+		'xhtmlOutput' => false, // only cssToInline
+		'removeCss' => true, // only cssToInline
+		'correctUtf8' => false // only cssToInline
 	);
 
-	public $settings = array();
+	public $config = array();
 
 	/**
-	 * startup
+	 * Inits with auto merged config.
 	 */
-	public function __construct($settings = array()) {
-		$defaults = am($this->_defaults, (array) Configure::read('InlineCss'));
-		$this->settings = array_merge($defaults, $settings);
-		if (!method_exists($this, '_process' . ucfirst($this->settings['engine']))) {
-			throw new InternalErrorException('Engine does not exist');
+	public function __construct($config = array()) {
+		$defaults = (array)Configure::read('InlineCss') + $this->_defaults;
+		$this->config = $config + $defaults;
+		if (!method_exists($this, '_process' . ucfirst($this->config['engine']))) {
+			throw new InternalErrorException('Engine does not exist: ' . $this->config['engine']);
 		}
 	}
 
 	/**
+	 * Processes HTML and CSS.
+	 *
 	 * @return string Result
 	 */
 	public function process($html, $css = null) {
 		if (($html = trim($html)) === '') {
 			return $html;
 		}
-		$method = '_process' . ucfirst($this->settings['engine']);
+		$method = '_process' . ucfirst($this->config['engine']);
 		return $this->{$method}($html, $css);
 	}
 
@@ -55,13 +62,24 @@ class InlineCssLib {
 	 * @return string Result
 	 */
 	protected function _processEmogrifier($html, $css) {
-		$css .= $this->_extractAndRemoveCss($html);
+		//$css .= $this->_extractAndRemoveCss($html);
 		App::import('Vendor', 'Tools.Emogrifier', array('file' => 'Emogrifier/Emogrifier.php'));
 
 		$Emogrifier = new Emogrifier($html, $css);
-		$Emogrifier->preserveEncoding = true;
+		//$Emogrifier->preserveEncoding = true;
+
+		$result = $Emogrifier->emogrify();
 
-		return @$Emogrifier->emogrify();
+		if ($this->config['cleanup']) {
+			// Remove comments and whitespace
+			$result = preg_replace( '/<!--(.|\s)*?-->/', '', $result);
+			$result = preg_replace( '/\s\s+/', '', $result);
+
+			// Result classes and ids
+			$result = preg_replace('/\bclass="[^"]*"/', '', $result);
+			$result = preg_replace('/\bid="[^"]*"/', '', $result);
+		}
+		return $result;
 	}
 
 	/**
@@ -81,23 +99,23 @@ class InlineCssLib {
 		}
 
 		$CssToInlineStyles = new CssToInlineStyles($html, $css);
-		if ($this->settings['cleanup']) {
+		if ($this->config['cleanup']) {
 			$CssToInlineStyles->setCleanup();
 		}
-		if ($this->settings['useInlineStylesBlock']) {
+		if ($this->config['useInlineStylesBlock']) {
 			$CssToInlineStyles->setUseInlineStylesBlock();
 		}
-		if ($this->settings['removeCss']) {
+		if ($this->config['removeCss']) {
 			$CssToInlineStyles->setStripOriginalStyleTags();
 		}
-		if ($this->settings['correctUtf8']) {
+		if ($this->config['correctUtf8']) {
 			$CssToInlineStyles->setCorrectUtf8();
 		}
-		if ($this->settings['debug']) {
+		if ($this->config['debug']) {
 			CakeLog::write('css', $html);
 		}
-		$html = $CssToInlineStyles->convert($this->settings['xhtmlOutput']);
-		if ($this->settings['removeCss']) {
+		$html = $CssToInlineStyles->convert($this->config['xhtmlOutput']);
+		if ($this->config['removeCss']) {
 			//$html = preg_replace('/\<style(.*)\>(.*)\<\/style\>/i', '', $html);
 			$html = $this->stripOnly($html, array('style', 'script'), true);
 			//CakeLog::write('css', $html);
@@ -157,6 +175,8 @@ class InlineCssLib {
 
 				// find the css file and load contents
 				if ($link->hasAttribute('media')) {
+					// FOR NOW
+					continue;
 					foreach ($this->mediaTypes as $cssLinkMedia) {
 						if (strstr($link->getAttribute('media'), $cssLinkMedia)) {
 							$css .= $this->_findAndLoadCssFile($link->getAttribute('href')) . "\n\n";
@@ -189,7 +209,7 @@ class InlineCssLib {
 		}
 
 		// Remove
-		if ($this->settings['removeCss']) {
+		if ($this->config['removeCss']) {
 			foreach ($removeDoms as $removeDom) {
 				try {
 					$removeDom->parentNode->removeChild($removeDom);
@@ -211,7 +231,9 @@ class InlineCssLib {
 		$cssFilenames = array_merge($this->_globRecursive(CSS . '*.Css'), $this->_globRecursive(CSS . '*.CSS'), $this->_globRecursive(CSS . '*.css'));
 
 		// Build an array of the ever more path specific $cssHref location
-		$cssHrefs = split(DS, $cssHref);
+		$cssHref = str_replace(array('\\', '/'), '/', $cssHref);
+
+		$cssHrefs = explode(DS, $cssHref);
 		$cssHrefPaths = array();
 		for ($i = count($cssHrefs) - 1; $i > 0; $i--) {
 			if (isset($cssHrefPaths[count($cssHrefPaths) - 1])) {
@@ -269,10 +291,6 @@ class InlineCssLib {
 	 * @return string Result
 	 */
 	protected function _parseInlineCssAndLoadImports($css) {
-		// Remove any <!-- --> comment tags - they are valid in HTML but we probably
-		// don't want to be commenting out CSS
-		$css = str_replace('-->', '', str_replace('<!--', '', $css)) . "\n\n";
-
 		// Load up the @import CSS if any exists
 		preg_match_all("/\@import.*?url\((.*?)\)/i", $css, $matches);
 

+ 25 - 0
Test/Case/Lib/InlineCssLibTest.php

@@ -206,4 +206,29 @@ bla';
 		$this->debug($result);
 	}
 
+	/**
+	 * InlineCssLibTest::testProcessSpecialChars()
+	 *
+	 * @return void
+	 */
+	public function testProcessCompleteTemplateAlternativeEngine() {
+		$path = CakePlugin::path('Tools') . 'Test' . DS . 'test_files' . DS . 'html' . DS;
+
+		$this->InlineCss = new InlineCssLib(array('engine' => InlineCssLib::ENGINE_EMOGRIFIER));
+		$html = file_get_contents($path . 'email_template.html');
+		$result = $this->InlineCss->process($html);
+		$this->debug($result);
+		$expected = '<td  style="vertical-align:top;';
+		$this->assertTextContains($expected, $result);
+
+		$this->InlineCss = new InlineCssLib(array('engine' => InlineCssLib::ENGINE_EMOGRIFIER));
+		$html = file_get_contents($path . 'email_template_utf8.html');
+		$result = $this->InlineCss->process($html);
+		$this->debug($result);
+		$expected = '<table  cellspacing="0" cellpadding="0" style=\'font-family:';
+		$this->assertTextContains($expected, $result);
+		$this->assertTextContains('香港酒店', $result);
+	}
+
+
 }

+ 107 - 0
Test/test_files/html/email_template.html

@@ -0,0 +1,107 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html>
+<head>
+		<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
+		<meta name="description" content="foo">
+		<title>Foo Confirmation</title>
+
+<style type="text/css">
+/* bugfixing for email clients */
+.ExternalClass {width:100%;} /* Forces Hotmail to display emails at full width */
+.ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div { line-height: 100%;}
+		/* Forces Hotmail to display normal line spacing, here is more on that:
+        http://www.emailonacid.com/forum/viewthread/43/
+        */
+
+body {							margin:0; padding:0; background-color: #BFB9B2; color: #646363; font-family: Arial,Verdana,Helvetica,sans-serif; font-size:12px;line-height:115%; }
+img {							border:0; }
+img a {							border:0; }
+table, td {						vertical-align:top;text-align:left;}
+table td 						{border-collapse:collapse;}
+/*This resolves the Outlook 07, 10, and Gmail td padding issue.  Heres more info:
+http://www.ianhoar.com/2008/04/29/outlook-2007-borders-and-1px-padding-on-table-cells
+http://www.campaignmonitor.com/blog/post/3392/1px-borders-padding-on-table-cells-in-outlook-07
+*/
+p {								padding:0; margin:0; margin-bottom:0; }
+label { 						padding-right:10px;}
+a, a:link {						text-decoration: none; color: #646363; }
+hr {							border: 0; width: 100%; color: #888888; background-color: #888888; height: 1px; }
+
+
+/***************************************
+*          Confirmation
+***************************************/
+
+/* main table */
+.mainTable {					width: 650px; border-collapse: collapse; border:0; background-color:#fff; font-family: Arial,Verdana,Helvetica,sans-serif; font-size:12px;color: #646363;line-height:115%;}
+.mainTableContentTD {			 width: 650px; padding-left:40px; padding-right:40px;}
+
+/* promotion2 */
+.promotionTable2 {				padding-top:0px; width:570px;}
+.promotionImage2 {				}
+
+/* footer */
+.footerTable {					padding-top:0px; width:570px; }
+.footerContent  {				color: #646363; text-align:center; padding-bottom:10px; font-family: Arial,Verdana,Helvetica,sans-serif; font-size:12px;line-height:150%;}
+.footerContent a,
+.footerContent a:link {			text-decoration: none; color: #646363;}
+
+/* end */
+</style>
+
+
+</head>
+
+<body>
+<center><br><br> 
+<!-- 
+************************************************************
+					Table: Logo & Banner
+************************************************************ 
+-->
+<table>
+<tbody>
+<tr>
+<td class="mainTableContentTD">
+<!-- 
+************************************************************
+			Table: Promotion 2
+************************************************************ 
+-->
+<table class="promotionTable2" cellpadding="0" cellspacing="0">
+<tbody>
+<tr>
+<td class="promotionImage2"><!-- {promotionImage} --> <img src="/img/foo/bar/hotel-promotion.jpg" alt="Foo" style="border: 0;" width="570"></td>
+</tr>
+</tbody>
+</table> 
+<!-- 
+********************************************************  
+--></td>
+</tr>
+<tr>
+<td style="font-size: 0; line-height: 0; height:20px;"> </td>
+</tr>
+<tr>
+<td class="mainTableContentTD">
+<!-- 
+************************************************************
+		         	Table: Footer
+************************************************************ 
+--> 
+<table class="footerTable" cellpadding="0" cellspacing="0">
+<tbody>
+<tr>
+<td class="footerContent"><strong>Foo Address</strong><br> Munich&nbsp;|&nbsp;Germany<br> <a href="mailto:info@foo.com" style="text-decoration: none; color: #646363;">info@foo.com</a> <br> T: +49 89 141283</td>
+</tr>
+</tbody>
+</table> <!-- ********************************************************  --></td>
+</tr>
+<tr>
+<td style="font-size: 0; line-height: 0; height:20px;"> </td>
+</tr>
+</tbody>
+</table>
+<br><br>
+</center>
+</body>
+</html>

文件差异内容过多而无法显示
+ 85 - 0
Test/test_files/html/email_template_utf8.html