/** * postbyemail_imap() * * Grabs unread messages from an imap account and saves them as .eml files * Passes any new messages found to the postby email function for processing * Called by a scheduled task or cronjob */ function postbyemail_imap() { global $modSettings; // No imap, why bother? if (!function_exists('imap_open')) { return false; } // Values used for the connection $hostname = !empty($modSettings['maillist_imap_host']) ? $modSettings['maillist_imap_host'] : ''; $username = !empty($modSettings['maillist_imap_uid']) ? $modSettings['maillist_imap_uid'] : ''; $password = !empty($modSettings['maillist_imap_pass']) ? $modSettings['maillist_imap_pass'] : ''; $mailbox = !empty($modSettings['maillist_imap_mailbox']) ? $modSettings['maillist_imap_mailbox'] : 'INBOX'; $type = !empty($modSettings['maillist_imap_connection']) ? $modSettings['maillist_imap_connection'] : ''; // I suppose that without these informations we can't do anything. if (empty($hostname) || empty($username) || empty($password)) { return; } // Based on the type selected get/set the additional connection details $connection = port_type($type); $hostname .= strpos($hostname, ':') === false ? ':' . $connection['port'] : ''; $server = '{' . $hostname . '/' . $connection['protocol'] . $connection['flags'] . '}'; $mailbox = $server . imap_utf7_encode($mailbox); // Connect to the mailbox using the supplied credentials and protocol $inbox = @imap_open($mailbox, $username, $password); if ($inbox === false) { return false; } // If using gmail, we may need the trash bin name as well $trash_bin = ''; if (!empty($modSettings['maillist_imap_delete']) && strpos($hostname, '.gmail.') !== false) { $trash_bin = get_trash_folder($inbox, $server); } // Grab all unseen emails, return by message ID $emails = imap_search($inbox, 'UNSEEN', SE_UID); // You've got mail, if ($emails) { // Initialize Emailpost controller require_once CONTROLLERDIR . '/Emailpost.controller.php'; $controller = new Emailpost_Controller(); // Make sure we work from the oldest to the newest message sort($emails); // For every email... foreach ($emails as $email_uid) { // Get the headers and prefetch the body as well to avoid a second request $headers = imap_fetchheader($inbox, $email_uid, FT_PREFETCHTEXT | FT_UID); $message = imap_body($inbox, $email_uid, FT_UID); // Create the save-as email if (!empty($headers) && !empty($message)) { $email = $headers . "\n" . $message; $controller->action_pbe_post($email); // Mark it for deletion? if (!empty($modSettings['maillist_imap_delete'])) { // Gmail labels make this more complicated if (strpos($hostname, '.gmail.') !== false) { imap_mail_move($inbox, $email_uid, $trash_bin, CP_UID); } imap_delete($inbox, $email_uid, FT_UID); imap_expunge($inbox); } } } // Close the connection imap_close($inbox); return true; } else { return false; } }
/** * Attempts to approve and post a failed email * * - Reviews the data to see if the email error function fixed typical issues like key and wrong id * - Submits the fixed email to the main function which will post it or fail it again * - If successful will remove the entry from the failed log * - Accessd by ?action=admin;area=maillist;sa=approve;item=?' * - Redirects to action=admin;area=maillist;sa=emaillist */ public function action_approve_email() { global $txt; allowedTo('approve_emails'); checkSession('get'); validateToken('admin-ml', 'get'); // Get the id to approve $id = (int) $_GET['item']; if (!empty($id) && $id !== -1) { // Load up the email data $temp_email = list_maillist_unapproved($id); if (!empty($temp_email)) { // Do we have the needed data to approve this, after all it failed for a reason yes? if (!empty($temp_email[0]['key']) && !in_array($temp_email[0]['error_code'], array('error_no_message', 'error_not_find_board', 'error_topic_gone'))) { // Set up the details needed to get this posted $force = true; $key = $temp_email[0]['key']; $data = $temp_email[0]['body']; // Unknown from email? Update the message ONLY if we found an appropriate one during the error checking process if (in_array($temp_email[0]['error_code'], array('error_not_find_member', 'error_key_sender_match'))) { // did we actually find a potential correct name, if so we post from the valid member $check_emails = array_pad(explode('=>', $temp_email[0]['from']), 2, ''); if (!empty($check_emails[1])) { $data = preg_replace('~(From: )(.*<)?(' . preg_quote(trim($check_emails[0])) . ')(>)?(\\n)~i', '$1$2' . trim($check_emails[1]) . '$4$5', $data); } } // Lets TRY AGAIN to make a post! include_once CONTROLLERDIR . '/Emailpost.controller.php'; $controller = new Emailpost_Controller(); $text = $controller->action_pbe_post($data, $force, $key); // Assuming all went well, remove this entry and file since we are done. if ($text === true) { maillist_delete_error_entry($id); // Flush the menu count cache cache_put_data('num_menu_errors', null, 900); $_SESSION['email_error'] = $txt['approved']; $_SESSION['email_error_type'] = 1; } else { $_SESSION['email_error'] = $txt['error_approved']; } } else { $_SESSION['email_error'] = $txt['cant_approve']; } } else { $_SESSION['email_error'] = $txt['badid']; } } else { $_SESSION['email_error'] = $txt['badid']; } // back to the list we go redirectexit('action=admin;area=maillist;sa=emaillist'); }
<?php /** * Handles the replying and posting of messages by email * * Note the shebang #!/usr/local/bin/php -q needs to point to the installed * location of php, this is the typical location but yours may be different * * @name ElkArte Forum * @copyright ElkArte Forum contributors * @license BSD http://opensource.org/licenses/BSD-3-Clause * * @version 1.0 * */ // Only do something for a pipe and direct calling if (!defined('STDIN')) { return; } // Any output here is not good error_reporting(0); // Need SSI to do much require_once dirname(__FILE__) . '/SSI.php'; // No need to ID the server if we fall on our face :) $_SERVER['SERVER_SOFTWARE'] = ''; $_SERVER['SERVER_NAME'] = ''; // Our mail controller require_once CONTROLLERDIR . '/Emailpost.controller.php'; $controller = new Emailpost_Controller(); $controller->action_pbe_post(); // Always exit as successful exit(0);