View source
<?php
define('INVISIMAIL_MAILTO_ASCII', 'mailto:');
function invisimail_help($section) {
switch ($section) {
case 'admin/help#invisimail':
return t('<p>The invisimail module privides a filter to hide email addresses from email harvesting spam-bots.</p><p>How it works: Invisimail scans content for email addresses and then converts each character of the address to its ASCII-code equivalent. The email address will appear normally on the page, but the source html will not appear as an email address. For even more security, the filter can use a JavaScript write command to further obscure the email address.</p><p>For example:<br /><i>you@example.com</i> will appear in the html source as: <div style="font-family:courier;border:1px solid #666;padding: 5px">&#121;&#111;&#117;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;</div></p><p>With the JavaScript and Auto-link options enabled, the source would become: <div style="font-family:courier;border:1px solid #666;padding: 5px"><script type=\'text/javascript\'><!--<br />
document.write(\'<a href= "&#109;&#97;&#105;&#108;&#116;&#111;&#58;\' + \'&#121;&#111;&#117;&#64;\' + \'&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;\' + \'&#99;&#111;&#109;\' + \'">\' + \'&#121;&#111;&#117;&#64;\' + \'&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;\' + \'&#99;&#111;&#109;\' + \'</a>\');<br />
//--><br />
</script></div></p><p>Doesn\'t look like an email address, does it?</p><p>Of course the best protection against spam-bots is to not publish an email address at all, but on a community site some users are going to publish email addresses. Invisimail provides another level of security to keep them from recieving spam.</p><p>To configure Invisimail, select "configure" next to the <a href="%url">input format</a> you\'d like to use. Enable "Encode Email Addresses" and submit the form. Then select the "configure" tab to choose options for Invisimail.</p>', array(
'%url' => url('admin/filters'),
));
}
}
function invisimail_menu() {
$items = array();
if (module_exists('email')) {
$items['admin/settings/invisimail'] = array(
'title' => t('Invisimail formatter'),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'invisimail_formatter_settings',
),
'access arguments' => array(
'administer invisimail formatter',
),
'type' => MENU_NORMAL_ITEM,
);
}
return $items;
}
function invisimail_perm() {
return array(
'administer invisimail formatter',
);
}
function invisimail_filter_tips($delta, $format, $long = FALSE) {
switch ($delta) {
case 0:
return t('Email addresses will be obfuscated in the page source to reduce the chances of being harvested by spammers.');
break;
}
}
function invisimail_filter($op, $delta = 0, $format = -1, $text = '') {
if ($op == 'list') {
return array(
0 => t('Encode email addresses'),
);
}
switch ($delta) {
case 0:
switch ($op) {
case 'description':
return t('Hide email addresses from spam-bots.');
case 'prepare':
return $text;
case 'process':
return invisimail($text, $format);
case 'settings':
$form['invisimail_settings'] = array(
'#type' => 'fieldset',
'#title' => t('Invisimail email address encoding filter'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['invisimail_settings'] += _invisimail_settings($format);
return $form;
}
break;
}
}
function invisimail($string, $format) {
$valid_user_chars = 'a-zA-Z0-9_\\-\\.\\+\\^!#\\$%&*+\\/\\=\\?\\`\\|\\{\\}~\'';
$user = "(?<![{$valid_user_chars}])[{$valid_user_chars}]+";
$domain = '(?:[a-zA-Z0-9](?:[a-zA-Z0-9\\-]*[a-zA-Z0-9])?\\.)+[a-zA-Z]{2,6}';
$ipv4 = '[0-9]{1,3}(?:\\.[0-9]{1,3}){3}';
$ipv6 = '[0-9a-fA-F]{1,4}(?:[0-9a-fA-F]{1,4}){7}';
$mail = "(?:{$user})+\\@(?:{$domain}|(?:\\[(?:{$ipv4}|{$ipv6})\\]))";
$modifiers = 'iS';
$pattern = "@(?:(<a [^>]*href=['\"](mailto:{$mail})['\"][^>]*>)?((?" . ">(?<!mailto:)){$mail}))|(<a [^>]*href=['\"](mailto:{$mail})['\"][^>]*>(.*?)</a>)@{$modifiers}";
$pattern_diff_link_text = "@(<a [^>]*href=['\"](mailto:{$mail})['\"][^>]*>(.*?)</a>)@{$modifiers}";
$pattern_same_link_text = "@(?:(<a [^>]*href=['\"](mailto:{$mail})['\"][^>]*>)?((?" . ">(?<!mailto:)){$mail}))@{$modifiers}";
$GLOBALS['invisimail_format'] = array(
'js' => variable_get('invisimail_js_' . $format, FALSE),
'link' => variable_get('invisimail_link_' . $format, FALSE),
);
if (variable_get('invisimail_chunk_' . $format, TRUE)) {
$substrings = preg_split('/(<a [^>]*>.+?<\\/a>)/', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
}
else {
$substrings = array(
$string,
);
}
$return = '';
foreach ($substrings as $phrase) {
$replaced_phrase = preg_replace_callback($pattern_diff_link_text, 'invisimail_callback', $phrase);
if ($error_code = preg_last_error()) {
watchdog('invisimail', 'preg_replace_callback failed on first pass with preg_last_error() of !code with pattern %pattern on text: !text', array(
'!code' => $error_code,
'%pattern' => check_plain($pattern_diff_link_text),
'!text' => check_plain($phrase),
), WATCHDOG_ERROR, request_uri());
}
$replaced_phrase = preg_replace_callback($pattern_same_link_text, 'invisimail_callback', $replaced_phrase);
if ($error_code = preg_last_error()) {
watchdog('invisimail', 'preg_replace_callback failed on second pass with preg_last_error() of !code with pattern %pattern on text: !text', array(
'!code' => $error_code,
'%pattern' => check_plain($pattern_same_link_text),
'!text' => check_plain($phrase),
), WATCHDOG_ERROR, request_uri());
}
$return .= $replaced_phrase;
}
return $return;
}
function invisimail_callback($matches) {
$format = $GLOBALS['invisimail_format'];
if (empty($matches[1])) {
return invisimail_ascii_encode($matches[3], $format['js'], $format['link']);
}
if ($matches[2] != 'mailto:' . $matches[3]) {
return str_replace($matches[2], _invisimail_encode_string($matches[2], FALSE), $matches[0]);
}
return str_replace(array(
$matches[2],
$matches[3],
), array(
_invisimail_encode_string($matches[2], FALSE),
_invisimail_encode_string($matches[3], FALSE),
), $matches[0]);
}
function invisimail_encode_add_link($string, $js, $text) {
static $counter = 0;
$encode = _invisimail_encode_string($string, $js);
$text = is_null($text) ? $encode : $text;
if ($js) {
$linkId = md5("mailto_link_{$counter}");
$counter++;
$output = "<span id=\"{$linkId}\"></span>";
$output .= "\n <script type=\"text/javascript\" > <!--\n document.getElementById('{$linkId}')\n .innerHTML = '<a href=\"" . INVISIMAIL_MAILTO_ASCII . "'+'{$encode}'+'\">'+'" . $text . "' + '</a>';" . "\n // --> </script>";
}
else {
$output = '<a href="' . INVISIMAIL_MAILTO_ASCII . "{$encode}\">{$text}</a>";
}
return $output;
}
function invisimail_ascii_encode($string, $js = FALSE, $link = FALSE, $text = NULL) {
return $link ? invisimail_encode_add_link($string, $js, $text) : _invisimail_encode_string($string, $js, $link);
}
function _invisimail_encode_string($string, $js, $link = FALSE) {
$encode = '';
for ($i = 0; $i < strlen($string); $i++) {
$char = substr($string, $i, 1);
$encode .= '&#' . ord($char) . ';';
if ($js && $link) {
if (in_array($char, array(
'.',
'@',
))) {
$encode .= "'+'";
}
}
}
return $encode;
}
function invisimail_field_formatter_info() {
return array(
'invisimail' => array(
'label' => t('Encode with Invisimail'),
'field types' => array(
'email',
),
'multiple values' => CONTENT_HANDLE_CORE,
),
);
}
function invisimail_theme() {
return array(
'invisimail_formatter_invisimail' => array(
'arguments' => array(
'element' => NULL,
),
),
);
}
function theme_invisimail_formatter_invisimail($element) {
if ($element['#item']['email'] == '') {
return;
}
if (module_exists('invisimail')) {
return invisimail_ascii_encode($element['#item']['email'], variable_get('invisimail_js_formatter', 0), variable_get('invisimail_link_formatter', 0));
}
else {
return '<a href="mailto:' . $element['#item']['email'] . '">' . check_plain($element['#item']['email']) . '</a>';
}
}
function invisimail_formatter_settings() {
return system_settings_form(_invisimail_settings('formatter'));
}
function _invisimail_settings($format) {
$form['invisimail_js_' . $format] = array(
'#type' => 'radios',
'#title' => t('JavaScript'),
'#default_value' => variable_get('invisimail_js_' . $format, 0),
'#options' => array(
0 => t('No JavaScript - greater compatibility'),
1 => t('Use JavaScript - greater security'),
),
'#description' => t('Selecting "Use JavaScript" will nearly guarantee protection from spam harvesters. However email addresses will not appear for browsers without JavaScript capability.'),
);
$form['invisimail_link_' . $format] = array(
'#type' => 'radios',
'#title' => t('Auto-link Emails'),
'#default_value' => variable_get('invisimail_link_' . $format, 0),
'#options' => array(
0 => t('Do not create links.'),
1 => t('Automatically create links from email addresses.'),
),
'#description' => t('Selecting "Automatically create links" will convert email addresses into a clickable "mailto:" link.'),
);
$form['invisimail_chunk_' . $format] = array(
'#type' => 'checkbox',
'#title' => t('Break up text for filtering'),
'#default_value' => variable_get('invisimail_chunk_' . $format, TRUE),
'#description' => t('Break up the text to be filtered into chunks with and
without anchor tags. Selecting this option may slow
down the filtering of text slightly, but will provide
better error messages in the <em>Recent log entries</em>
should content not render as you expect it when there
are e-mail addresses to obfuscate.'),
);
return $form;
}