Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
403 lines (380 sloc) 12.8 KB
<?php
// $Id$
/**
* Implementation of hook_perm().
*/
function mailhandler_perm() {
return array('administer mailhandler');
}
/**
* Implementation of hook_menu().
*/
function mailhandler_menu() {
$items = array();
// @TODO may need to add this button in to ctools, but may not make sense
// now with Feeds integration.
$items['admin/content/mailhandler/retrieve/%mailhandler_mailbox'] = array(
'title' => 'Retrieve',
'page callback' => 'mailhandler_node_process_mailbox',
// Cast variable as string so menu system does not mistake it for a path argument
'page arguments' => array(4, 'ui', (string) variable_get('mailhandler_max_retrieval', 0)),
'access arguments' => array('administer mailhandler'),
'type' => MENU_CALLBACK,
'file' => 'mailhandler.retrieve.inc',
);
$items['admin/content/mailhandler/toggle'] = array(
'title' => 'Toggle mailbox type',
'page callback' => 'mailhandler_mailbox_toggle_type',
'access arguments' => array('administer mailhandler'),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implementation of hook_help().
*/
function mailhandler_help($path = 'admin/help#mailhandler', $arg) {
; // TODO: Update help text.
}
/**
* Implementation of hook_mail().
*/
function mailhandler_mail($key, &$message, $params) {
$variables = array(
'!body' => $params['body'],
'!from' => $params['from'],
'!site_name' => variable_get('site_name', 'Drupal'),
'!subject' => $params['header']->subject,
'!type' => $params['node']->type,
);
$message['subject'] = t('Email submission to !site_name failed - !subject', $variables);
$message['body'][] = $params['error_text'];
foreach ($params['error_messages'] as $key => $error) {
$message['body'][$key] = decode_entities(strip_tags($error));
}
$message['body'][] = t("You sent:\n\nFrom: !from\nSubject: !subject\nBody:\n!body", $variables);
}
/**
* Determine from address either using the mailbox setting or via the header information
*
* @param $header
* Object message header information
* @param $mailbox
* Array mailbox settings
* @return array
*/
function mailhandler_get_fromaddress($header, $mailbox) {
if (($fromheader = strtolower($mailbox->fromheader)) && isset($header->$fromheader)) {
$from = $header->$fromheader;
}
else {
$from = $header->from;
}
return array($from[0]->mailbox .'@'. $from[0]->host, (isset($from[0]->personal)) ? $from[0]->personal : '');
}
/**
* Retrieve user information from his email address.
*/
function mailhandler_user_load($mail, $pass, $mailbox) {
if ($mailbox->security == 1) {
if (!$account = user_load(array('mail' => $mail, 'pass' => $pass))) {
watchdog('mailhandler', 'Wrong password used in message commands for %address', array('%address' => $mail), WATCHDOG_NOTICE);
}
return $account;
}
else {
return user_load(array('mail' => $mail));
}
}
/**
* @TODO this should not live here.
*
* Look up a user based on their mailalias addresses
*
* Helper function for mailhandler_authenticate_tokenauth()
*
* @param $fromaddress
* String from address
* @param $node
* Object node object
* @param $mailbox
* Array of mailhandler mailbox configuration
*
* @return Object user object or FALSE
*/
function mailhandler_user_load_alias($fromaddress, $node, $mailbox) {
$result = db_query("SELECT mail FROM {users} WHERE data LIKE '%%%s%%'", $fromaddress);
while ($alias = db_result($result)) {
if ($from_user = mailhandler_user_load($alias, $node->pass, $mailbox)) {
return $from_user;
break;
}
}
return FALSE;
}
/**
* Implementation of hook_ctools_plugin_api()
*/
function mailhandler_ctools_plugin_api($module, $api) {
if ($module == 'mailhandler' && $api == 'mailhandler_default') {
return array(
'version' => 1,
'file' => 'mailhandler.mailhandler_default.inc',
'path' => drupal_get_path('module', 'mailhandler'),
);
}
elseif ($module == 'mailhandler' && $api == 'mailbox_plugin') {
return array(
'version' => 1
);
}
}
/**
* Implementation of hook_theme()
*/
function mailhandler_theme() {
$hooks = array();
$hooks['mailhandler_mailbox_form'] = array(
'form' => array(),
);
return $hooks;
}
/*
*
* @TODO finish this documentation
*
* Cases
*
* Load all mailboxes for summary
* - $name is FALSE
* - $new is FALSE
*
* Load existing mailbox
* - $name is mailbox name, like foo@example.com
* - $new is FALSE
*
* Load new mailbox
* - $name is mailbox type
* - $new is TRUE
*
*/
function mailhandler_mailboxes_load($name = '', $new = FALSE) {
// Load all mailboxes for summary
$args = array(); $mailbox = FALSE;
// If $name is string, we're actually creating a new mailbox of $name type.
if (!$new) {
ctools_include('export');
$mailboxes = ctools_export_load_object('mailhandler');
if (!$name) {
return $mailboxes;
}
else {
$mailbox = $mailboxes[$name];
$name = $mailbox->mailbox_type;
}
}
// Load mailbox. When no $mailbox arg is present, new object will be instantiated.
// Otherwise, existing object is loaded.
if ($object = mailhandler_plugin_load_class('mailhandler', $name, 'mailbox_plugin', 'handler', $mailbox)) {
return $object;
}
else {
return FALSE;
}
}
/**
* Implementation of hook_mailhandler_mailbox().
*/
function mailhandler_mailhandler_mailbox_plugin() {
$plugins = array();
$plugins['MailhandlerMailbox'] = array(
'handler' => array(
'path' => drupal_get_path('module', 'mailhandler') .'/plugins',
'file' => 'MailhandlerMailbox.inc',
'class' => 'MailhandlerMailbox',
# 'parent' => '',
),
);
return $plugins;
}
/**
* Implementation of hook_feeds_plugins().
*/
function mailhandler_feeds_plugins() {
$info = array();
$info['MailhandlerFetcher'] = array(
'name' => 'Mailhandler fetcher',
'description' => 'Connects to an IMAP/POP mailbox.',
'handler' => array(
'parent' => 'FeedsFetcher',
'class' => 'MailhandlerFetcher',
'file' => 'MailhandlerFetcher.inc',
'path' => drupal_get_path('module', 'mailhandler') . '/plugins',
),
);
$info['MailhandlerParser'] = array(
'name' => 'Mailhandler IMAP stream parser',
'description' => 'Parses an IMAP stream.',
'handler' => array(
'parent' => 'FeedsParser',
'class' => 'MailhandlerParser',
'file' => 'MailhandlerParser.inc',
'path' => drupal_get_path('module', 'mailhandler') . '/plugins',
),
);
return $info;
}
/*
* Wrapper to load any class type
*/
function mailhandler_plugin_load_class($module, $plugin, $type, $id, $args = NULL) {
ctools_include('plugins');
if ($class = ctools_plugin_load_class($module, $type, $plugin, 'handler')) {
return new $class($args);
}
// TODO: handle case where plugin is unable to load.
}
/**
* @TODO document this.
*
* @param $type
* String - type of mailhandler plugins to retrieve.
*/
function mailhandler_get_plugins($module, $type) {
ctools_include('plugins');
$plugins = ctools_get_plugins($module, $type);
$result = array();
foreach ($plugins as $key => $info) {
if (!empty($info['hidden'])) {
continue;
}
$result[$key] = $info;
}
return $result;
}
/**
* Implementation of hook_ctools_plugin_directory().
*/
function mailhandler_ctools_plugin_directory($module, $plugin) {
if ($module == 'ctools' && $plugin == 'export_ui') {
return 'plugins/' . $plugin;
}
}
/**
* Return a form for editing or creating an individual mailbox.
*
* This design was somewhat influenced by the lack of late static bindings in
* PHP < 5.3
*/
function mailhandler_mailbox_form(&$form, &$form_state, $type = 'MailhandlerMailbox') {
$form['#theme'] = 'mailhandler_mailbox_form';
// Set some values which will be used below as well as in the submit handler.
// @TODO mangling the #form here could probably be cleaned up, avoided.
$type = $form_state['function args'][3] ? $form_state['function args'][3] : 'MailhandlerMailbox';
$mail = $form['info']['mail']['#value'];
$form['#mailhandler_mail'] = $form['info']['mail']['#value'];
$form['#mailhandler_class'] = $type;
$form['#mailhandler_op'] = $form_state['op'];
if ($form_state['op'] == 'edit') {
// Load the object and get its type
$mailbox = mailhandler_mailboxes_load($mail);
// Store the instantiated object on the form
$form['#mailhandler_mailbox'] = $mailbox;
$defaults = $mailbox->getSettings();
$defaults = $defaults[$type];
}
// Make sure the class is loaded, then call its form.
if ($class = mailhandler_plugin_load_class('mailhandler', $type, 'mailbox_plugin', 'handler')) {
$form += call_user_func_array(array($class, 'form'), array($form_state, $defaults));
}
// Hack to remove ctools forcing in 'name' identifier, whose validation does not allow '@ nor .'.
// This will get validated by the object itself.
$form['info']['mail']['#element_validate'] = NULL;
// More accurate language on the ctools-provided name/mail field.
$form['info']['mail']['#title'] = t('E-mail address');
$form['info']['mail']['#description'] = t('The e-mail address to which users should send their submissions.');
// TODO: else, fail gracefully.
return $form;
}
/**
* Call validate() on the mailbox object.
*/
function mailhandler_mailbox_form_validate($form, &$form_state) {
if ($class = mailhandler_plugin_load_class('mailhandler', $form['#mailhandler_class'], 'mailbox_plugin', 'handler')) {
call_user_func_array(array($class, 'validate'), array($form, &$form_state));
}
}
/**
* Prepare values for saving by ctools export UI. Pushing the data to the database is handled by ctools Export UI.
*/
function mailhandler_mailbox_form_submit($form, &$form_state) {
//@TODO avoid storing the form information.
// Export UI requires moving values into $form_state['item'] in preparation for storage.
$form_state['item']->mail = $form_state['values']['mail'];
// Only affect the settings key which pertains to the mailbox Type currently being edited.
if ($form['#mailhandler_mailbox'] && $current = db_result(db_query("SELECT settings FROM {mailhandler} WHERE mail = '%s'", $form_state['values']['mail']))) {
$current = unserialize($current);
$current[$form['#mailhandler_class']] = $form_state['values'];
$form_state['item']->settings = $current;
}
else {
// Adding a new record. Set the mailbox_type
$form_state['item']->mailbox_type = 'MailhandlerMailbox';
$form_state['item']->settings[$form['#mailhandler_class']] = $form_state['values'];
}
}
/**
* Theme function for theme('mailhandler_mailbox_form')
*/
function theme_mailhandler_mailbox_form($form) {
drupal_add_css(drupal_get_path('module', 'mailhandler') .'/mailhandler.css');
$output = '<div class="mailhandler-settings clear-block">';
$output .= '<div class="left-bar">';
$plugins = mailhandler_get_plugins('mailhandler', 'mailbox_plugin');
foreach ($plugins as $plugin) {
$object = FALSE;
$object = mailhandler_plugin_load_class('mailhandler', $plugin['name'], 'mailbox_plugin', 'handler');
$info = $object->getInfo();
$output .= '<div class="mailhandler-settings-container">';
$output .= '<h4 class="mailhandler-settings-container-title">';
$output .= t($info['title']);
$output .= '</h4>';
$output .= '<div class="mailhandler-settings-container-body '.$zebra.'">';
$output .= '<div class="mailhandler-settings-desc">';
$output .= t($info['description']);
$output .= '<div class="mailhandler-settings-container-operations">';
$output .= l(t('Edit'), 'admin/content/mailhandler/list/'.$form['#mailhandler_mail'].'/edit/'.$plugin['name']);
if ($form['#mailhandler_op'] == 'edit') {
if ($plugin['name'] != $form['#mailhandler_mailbox']->mailbox_type) {
$output .= l(t('Set active'), 'admin/content/mailhandler/toggle/'.$form['#mailhandler_mail'].'/'.$plugin['name'] .'/'.$info['title'], array('query' => drupal_get_destination()));
}
else {
$output .= t('%active', array('%active' => 'Active'));
}
}
$output .= '</div></div></div></div>';
}
$output .= '</div>';
$output .= '<div class="main-bar">';
$output .= drupal_render($form);
$output .= '</div';
$output .= '</div>';
return $output;
}
/**
* Toggles the active mailbox type for a mailbox.
*
* @param $mail
* The mail identifier
* @param $type
* The mailbox Type to toggle as active
* @param $title
* The title of the mailbox Type.
*/
function mailhandler_mailbox_toggle_type($mail, $type, $title) {
if ($mailbox = db_fetch_object(db_query("SELECT * FROM {mailhandler} WHERE mail = '%s'", $mail))) {
db_query("UPDATE {mailhandler} SET mailbox_type = '%s' WHERE mail = '%s'", $type, $mail);
drupal_set_message(t('%type is now the active mailbox type.', array('%type' => $title)));
drupal_goto(drupal_get_destination());
}
}