View source
<?php
if (!function_exists('url_to_path')) {
require_once dirname(__FILE__) . '/url_to_path.inc';
}
function emogrifier_help($path = 'admin/help#emogrifier', $arg) {
switch ($path) {
case 'admin/help#emogrifier':
return '<p>' . t('The <a href="!module">%emogrifier</a> module uses the <a href="!class">%emogrifier</a> class library to convert stylesheet rules to inline style attributes. This ensures proper display on email and mobile device readers that lack stylesheet support.', array(
'!module' => url('http://drupal.org/project/emogrifier'),
'%emogrifier' => 'emogrifier',
'!class' => url('http://www.pelagodesign.com/sidecar/emogrifier/'),
)) . '</p>';
break;
}
}
function emogrifier_filter_info() {
return array(
'filter_emogrifier' => array(
'title' => t('Emogrifier'),
'description' => t('Converts stylesheet rules to inline style attributes.'),
'process callback' => '_emogrifier_process',
'settings callback' => '_emogrifier_filter_settings',
'tips callback' => '_emogrifier_filter_tips',
),
);
}
function _emogrifier_process($text, $filter, $format, $langcode, $cache, $cache_id) {
if (empty($text)) {
return '';
}
if (!extension_loaded('dom')) {
watchdog('emogrifier', 'The PHP <a href="!dom">%dom</a> extension required by <a href="!emogrifier">%emogrifier</a> is not loaded.', array(
'!dom' => url('http://php.net/dom'),
'%dom' => 'dom',
'!emogrifier' => url('http://drupal.org/project/emogrifier'),
'%emogrifier' => 'Emogrifier',
), LOG_WARNING);
return $text;
}
if (!_emogrifier_available()) {
watchdog('emogrifier', 'The <a href="!library">%emogrifier</a> class library required by the <a href="!module">%emogrifier</a> module could not be loaded.', array(
'!library' => url('http://www.pelagodesign.com/sidecar/emogrifier/'),
'%emogrifier' => 'emogrifier',
'!module' => url('http://drupal.org/project/emogrifier'),
), LOG_WARNING);
return $text;
}
$styles = array();
$urls = array();
if (preg_match_all('#<link[^>]*>\\s*#si', $text, $links)) {
foreach ($links[0] as $link) {
if (preg_match('#\\s+type\\s*=\\s*(["\']?)text/css\\1#si', $link) && preg_match('#\\s+rel\\s*=\\s*(["\']?)stylesheet\\1#si', $link) && preg_match('#\\s+media\\s*=\\s*(["\']?)all\\1#si', $link) && preg_match('#\\s+href\\s*=\\s*(["\']?)([^?]*?)(\\?.*?)?\\1#si', $link, $match)) {
$urls = array_merge($urls, array_slice($match, 2, 1));
}
$text = str_replace($link, '', $text);
}
}
if (preg_match_all('#(<style[^>]*>)\\s*(<!--)?\\s*(.*?)\\s*(-->)?\\s*</style>\\s*#si', $text, $blocks)) {
foreach ($blocks[1] as $block => $tag) {
if (preg_match('#\\s+type\\s*=\\s*(["\']?)text/css\\1#si', $tag) && preg_match('#\\s+media\\s*=\\s*(["\']?)all\\1#si', $tag)) {
if (preg_match_all('#@import\\s+url\\s*\\(\\s*(["\']?)([^?]*)(\\?.*?)?\\1\\s*\\)\\s*;#si', $blocks[3][$block], $imports)) {
$urls = array_merge($urls, $imports[2]);
$rules = trim(str_replace($imports[0], '', $blocks[3][$block]));
if (!empty($rules)) {
$styles[] = $rules;
}
}
}
}
$text = str_replace($blocks[0], '', $text);
}
foreach ($urls as $url) {
if (($path = url_to_realpath(check_url($url))) && file_exists($path) && ($style = trim(file_get_contents($path)))) {
$styles[] = $style;
}
}
$styles = preg_replace(array(
'/[[:space:]]+/s',
'#/\\*.*?\\*/#',
'/ +/',
), ' ', $styles);
$styles = preg_replace('/url[[:space:]]*\\([[:space:]]*(["\'])(.*?)\\1[[:space:]]*\\)/mis', 'url(\\2)', $styles);
$text = preg_replace('/url[[:space:]]*\\([[:space:]]*(["\'])(.*?)\\1[[:space:]]*\\)/mis', 'url(\\2)', $text);
$styles = preg_replace('/}\\s*/', "}\n", implode("\n", $styles));
$text = preg_replace('#<(applet|audio|canvas|embed|frameset|head|iframe|object|ruby|script|style|title|video)[^[:alnum:]].*?</\\1\\s*>\\s*#si', '', '<head>' . $text);
$text = preg_replace_callback('#(<(/?))([!\\[[:alnum:]\\]]{2,12})([^>]*>)#s', '_emogrifier_replace_tag', $text);
$text = preg_replace('#<!--.*?-->\\s*#si', '', $text);
$emogrifier = new Emogrifier('<html><body>' . $text . '</body></html>', $styles);
$text = @$emogrifier
->emogrify();
$text = preg_replace('#.*<body>(.*)</body>.*#Usi', '\\1', $text);
$text = preg_replace(array(
'#(<[^>]*?)\\s*class\\s*=\\s*(["\']).*?\\2#si',
'#(<[^>]*?)\\s*id\\s*=\\s*(["\']).*?\\2#si',
), '\\1', $text);
return $text;
}
function _emogrifier_replace_tag(array $matches) {
static $allowed;
if (!isset($allowed)) {
$allowed =& emogrifier_allowed_tags();
}
return isset($allowed[$name = strtolower($matches[3])]) ? is_array($tag = $allowed[$name]) ? $tag[(bool) $matches[2]] : $matches[1] . $tag . $matches[4] : '';
}
function &emogrifier_allowed_tags() {
$tags = drupal_static(__FUNCTION__);
if (!isset($tags)) {
$tags = variable_get('emogrifier_allowed_tags', array_combine($a = explode(',', 'a,abbr,address,area,b,bdo,blockquote,br,button,caption,cite,' . 'code,col,colgroup,dd,del,dfn,div,dl,dt,em,fieldset,font,form,h1,h2,' . 'h3,h4,h5,h6,hr,i,img,input,ins,kbd,label,legend,li,map,ol,optgroup,' . 'option,p,pre,q,s,samp,select,span,strike,strong,sub,sup,table,' . 'tbody,td,textarea,tfoot,th,thead,tr,tt,u,ul,var,'), $a) + array_fill_keys(explode(',', 'acronym,meter,output,progress,time'), 'span') + array_fill_keys(explode(',', 'article,aside,body,details,figcaption,figure,footer,header,' . 'hgroup,nav,section,summary'), 'div') + array(
'big' => array(
'<span style="font-size: 120%">',
'</span>',
),
'center' => array(
'<div style="text-align: center">',
'</div>',
),
'command' => 'button',
'datalist' => 'select',
'dir' => 'ul',
'mark' => array(
'<span style="background-color: yellow; color: black">',
'</span>',
),
'menu' => 'ul',
's' => array(
'<span style="text-decoration: line-through">',
'</span>',
),
'small' => array(
'<span style="font-size: 80%">',
'</span>',
),
'strike' => array(
'<span style="text-decoration: line-through">',
'</span>',
),
'wbr' => array(
'­',
'',
),
'xmp' => 'pre',
));
}
return $tags;
}
function _emogrifier_available() {
if (class_exists('Emogrifier')) {
return TRUE;
}
@(include_once libraries_get_path('emogrifier') . '/emogrifier.php');
return class_exists('Emogrifier');
}
function _emogrifier_filter_settings($form, &$form_state, $filter, $format, $defaults, $filters) {
return array();
}
function _emogrifier_filter_tips($filter, $format, $long) {
return t('Stylesheet rules will be converted to inline style attributes.');
}