View source
<?php
function mailhandler_open_mailbox($mailbox) {
if ($mailbox['domain']) {
if ($mailbox['imap'] == 1) {
$box = '{' . $mailbox['domain'] . ':' . $mailbox['port'] . $mailbox['extraimap'] . '}' . $mailbox['folder'];
}
else {
$box = '{' . $mailbox['domain'] . ':' . $mailbox['port'] . '/pop3' . $mailbox['extraimap'] . '}' . $mailbox['folder'];
}
$result = imap_open($box, $mailbox['name'], $mailbox['pass']);
$err = 'domain';
}
else {
$box = $mailbox['folder'];
$result = imap_open($box, '', '');
}
return $result;
}
function mailhandler_get_part($stream, $msg_number, $mime_type, $structure = false, $part_number = false) {
if (!$structure) {
$structure = imap_fetchstructure($stream, $msg_number, FT_UID);
}
if ($structure) {
$encoding = variable_get('mailhandler_default_encoding', 'UTF-8');
foreach ($structure->parameters as $parameter) {
if (strtoupper($parameter->attribute) == 'CHARSET') {
$encoding = $parameter->value;
}
}
if ($mime_type == mailhandler_get_mime_type($structure)) {
if (!$part_number) {
$part_number = '1';
}
$text = imap_fetchbody($stream, $msg_number, $part_number, FT_UID);
if ($structure->encoding == ENCBASE64) {
return drupal_convert_to_utf8(imap_base64($text), $encoding);
}
else {
if ($structure->encoding == ENCQUOTEDPRINTABLE) {
return drupal_convert_to_utf8(quoted_printable_decode($text), $encoding);
}
else {
return drupal_convert_to_utf8($text, $encoding);
}
}
}
if ($structure->type == TYPEMULTIPART) {
$prefix = '';
while (list($index, $sub_structure) = each($structure->parts)) {
if ($part_number) {
$prefix = $part_number . '.';
}
$data = mailhandler_get_part($stream, $msg_number, $mime_type, $sub_structure, $prefix . ($index + 1));
if ($data) {
return $data;
}
}
}
}
return false;
}
function mailhandler_get_parts($stream, $msg_number, $max_depth = 10, $depth = 0, $structure = FALSE, $part_number = FALSE) {
$parts = array();
if (!$structure && !($structure = imap_fetchstructure($stream, $msg_number, FT_UID))) {
watchdog('mailhandler', 'Could not fetch structure for message number %msg_number', array(
'%msg_number' => $msg_number,
), WATCHDOG_NOTICE);
return $parts;
}
if ($structure->type == TYPEMULTIPART) {
if ($depth >= $max_depth) {
watchdog('mailhandler', 'Maximum recursion depths met in mailhander_get_structure_part for message number %msg_number.', array(
'%msg_number' => $msg_number,
), WATCHDOG_NOTICE);
return $parts;
}
$prefix = '';
foreach ($structure->parts as $index => $sub_structure) {
if ($part_number) {
$prefix = $part_number . '.';
}
$sub_parts = mailhandler_get_parts($stream, $msg_number, $max_depth, $depth + 1, $sub_structure, $prefix . ($index + 1));
$parts = array_merge($parts, $sub_parts);
}
return $parts;
}
$part = new StdClass();
$part->attributes = array();
$part->filename = 'unnamed_attachment';
if (!($part->filemime = mailhandler_get_mime_type($structure))) {
watchdog('mailhandler', 'Could not fetch mime type for message part. Defaulting to application/octet-stream.', array(), WATCHDOG_NOTICE);
$part->filemime = 'application/octet-stream';
}
if ($structure->ifparameters) {
foreach ($structure->parameters as $parameter) {
switch (strtoupper($parameter->attribute)) {
case 'NAME':
case 'FILENAME':
$part->filename = $parameter->value;
break;
default:
$part->attributes[$parameter->attribute] = $parameter->value;
}
}
}
if ($structure->type != TYPETEXT && $structure->ifdparameters) {
foreach ($structure->dparameters as $parameter) {
switch (strtoupper($parameter->attribute)) {
case 'NAME':
case 'FILENAME':
$part->filename = $parameter->value;
break;
default:
$part->attributes[$parameter->attribute] = $parameter->value;
}
}
}
if (!($part->data = imap_fetchbody($stream, $msg_number, $part_number, FT_UID))) {
watchdog('mailhandler', 'No Data!!', array(), WATCHDOG_ERROR);
return $parts;
}
if ($structure->encoding == ENCBASE64) {
$part->data = imap_base64($part->data);
}
elseif ($structure->encoding == ENCQUOTEDPRINTABLE) {
$part->data = quoted_printable_decode($part->data);
}
elseif ($structure->type == TYPETEXT) {
$part->data = imap_utf8($part->data);
}
$parts[] = $part;
return $parts;
}
function mailhandler_get_mime_type(&$structure) {
static $primary_mime_type = array(
'TEXT',
'MULTIPART',
'MESSAGE',
'APPLICATION',
'AUDIO',
'IMAGE',
'VIDEO',
'OTHER',
);
$type_id = (int) $structure->type;
if (isset($primary_mime_type[$type_id]) && !empty($structure->subtype)) {
return $primary_mime_type[$type_id] . '/' . $structure->subtype;
}
return 'TEXT/PLAIN';
}
function mailhandler_commands_parse($body, $sep) {
$commands = array();
$lines = explode("\n", $body);
for ($i = 0; $i < count($lines); $i++) {
$line = trim($lines[$i]);
$words = explode(' ', $line);
if (substr($words[0], -1) == ':' && !isset($endcommands)) {
$commands[$i] = explode(': ', $line, 2);
}
else {
if (!isset($endcommands)) {
$endcommands = $i;
}
}
$start = substr($lines[$i], 0, strlen($sep) + 3);
if ($sep && strstr($start, $sep)) {
break;
}
}
return array(
'commands' => $commands,
'lines' => $lines,
'i' => $i,
'endcommands' => $endcommands,
);
}
function mailhandler_mailhandler_authenticate($op, $name = NULL, $args = array()) {
$methods = array();
switch ($op) {
case 'info':
foreach (module_list() as $module) {
if (module_hook($module, 'mailhandler_authenticate_info')) {
$function = $module . '_mailhandler_authenticate_info';
$methods[] = $function();
}
}
return $methods;
case 'execute':
foreach (module_list() as $module) {
if (module_hook($module, 'mailhandler_authenticate_info')) {
$function = $module . '_mailhandler_authenticate_info';
$methods = $function('info');
foreach ($methods as $key => $method) {
if ($name == $key) {
if ($method['extension'] && $method['basename']) {
module_load_include($method['extension'], $method['module'], $method['basename']);
return call_user_func_array($method['callback'], $args);
}
else {
drupal_load('module', $method['module']);
return call_user_func_array($method['callback'], $args);
}
break 2;
}
}
}
}
return FALSE;
break;
}
}
function mailhandler_switch_user($uid = NULL) {
global $user;
static $orig_user = array();
if (isset($uid)) {
session_save_session(FALSE);
$user = user_load(array(
'uid' => $uid,
));
}
else {
if (count($orig_user)) {
$user = array_shift($orig_user);
session_save_session(TRUE);
array_unshift($orig_user, $user);
}
else {
$orig_user[] = $user;
}
}
}
function mailhandler_batch_finished($success, $results, $operations) {
if ($success) {
$message = format_plural(count($results), '1 message retrieved for %mailbox.', '@count messages retrieved for %mailbox.', array(
'%mailbox' => $results[0]['mailbox']['mail'],
));
drupal_set_message($message);
}
if (!empty($results)) {
foreach (module_list() as $name) {
if (module_hook($name, 'mailhandler_batch_results')) {
$function = $name . '_mailhandler_batch_results';
if (!($messages = $function($results))) {
break;
}
}
}
}
}
function mailhandler_get_unread_messages($result) {
$unread_messages = array();
$number_of_messages = imap_num_msg($result);
for ($i = 1; $i <= $number_of_messages; $i++) {
$header = imap_header($result, $i);
if ($header->Unseen != 'U' && $header->Recent != 'N') {
continue;
}
$unread_messages[] = imap_uid($result, $i);
}
return $unread_messages;
}
function mailhandler_retrieve_message($result, $mailbox, $i, &$context) {
if (!$result) {
$result = mailhandler_open_mailbox($mailbox);
}
$header = imap_header($result, imap_msgno($result, $i));
if (!isset($header->subject)) {
$header->subject = '';
}
$mime = explode(',', $mailbox['mime']);
$origbody = mailhandler_get_part($result, $i, $mime[0]);
if (!$origbody) {
$origbody = mailhandler_get_part($result, $i, $mime[1]);
}
$mimeparts = mailhandler_get_parts($result, $i);
if (!$origbody && !$mimeparts) {
imap_close($result);
return;
}
if ($mailbox['delete_after_read']) {
imap_delete($result, $i, FT_UID);
}
$message = array(
'header' => $header,
'origbody' => $origbody,
'mimeparts' => $mimeparts,
'mailbox' => $mailbox,
);
if (!empty($context) && array_key_exists('sandbox', $context)) {
$context['results'][] = $message;
imap_close($result, CL_EXPUNGE);
}
else {
return $message;
}
}
function mailhandler_retrieve($mailbox, $mode, $limit = 0) {
$limit = (int) $limit;
if ($result = mailhandler_open_mailbox($mailbox)) {
$new = mailhandler_get_unread_messages($result);
}
switch ($mode) {
case 'ui':
if ($result) {
imap_close($result, CL_EXPUNGE);
$result = 0;
if (!empty($new)) {
foreach ($new as $message) {
$message_number = !$mailbox['imap'] ? 1 : $message;
$operations[] = array(
'mailhandler_retrieve_message',
array(
$result,
$mailbox,
$message_number,
),
);
}
$batch = array(
'title' => 'Mailhandler retrieve',
'operations' => $operations,
'finished' => 'mailhandler_batch_finished',
'init_message' => format_plural(count($new), 'Preparing to retrieve 1 message...', 'Preparing to retrieve @count messages...'),
'progress_message' => t('Retrieving message @current of @total.'),
'file' => drupal_get_path('module', 'mailhandler') . '/mailhandler.retrieve.inc',
);
batch_set($batch);
$batch =& batch_get();
$batch['progressive'] = FALSE;
batch_process('admin/content/mailhandler');
}
else {
drupal_set_message(t('There are no messages to retrieve for %mail.', array(
'%mail' => $mailbox['mail'],
)));
}
}
else {
drupal_set_message(t('Unable to connect to %mail.', array(
'%mail' => $mailbox['mail'],
)));
}
drupal_goto('admin/content/mailhandler');
break;
case 'auto':
if ($result) {
if (!empty($new)) {
$messages = array();
$retrieved = 0;
while ($new && (!$limit || $retrieved < $limit)) {
$messages[] = mailhandler_retrieve_message($result, $mailbox, array_shift($new), $context = array());
$retrieved++;
}
imap_close($result, CL_EXPUNGE);
return $messages;
}
}
else {
watchdog('mailhandler', 'Unable to connect to %mail', array(
'%mail' => $mailbox['mail'],
), WATCHDOG_ERROR);
}
break;
}
}