/**
  * Main email posting controller, reads, parses, checks and posts an email message or PM
  *
  * What it does:
  * - Allows a user to reply to a topic on the board by emailing a reply to a
  * notification message.
  * - It must have the security key in the email or it will be rejected
  * - It must be from the email of a registered user
  * - The key must have been sent to that user
  * - Keys are used once and then discarded
  * - Accessed by email imap cron script, and ManageMaillist.controller.php.
  *
  * @param string|null $data used to supply a full headers+body email
  * @param boolean $force used to override common failure errors
  * @param string|null $key used to supply a lost key
  */
 public function action_pbe_post($data = null, $force = false, $key = null)
 {
     global $txt, $modSettings, $language, $user_info, $maintenance;
     // The function is not even on ...
     if (empty($modSettings['maillist_enabled'])) {
         return;
     }
     // Our mail parser and our main subs
     require_once SUBSDIR . '/EmailParse.class.php';
     require_once SUBSDIR . '/Emailpost.subs.php';
     // Init
     loadLanguage('Maillist');
     setMemoryLimit('128M');
     // Load the email parser and get some data to work with
     $email_message = new Email_Parse();
     $email_message->read_data($data, BOARDDIR);
     if (!$email_message->raw_message) {
         return false;
     }
     // Ask for an html version (if available) and some needed details
     $email_message->read_email(true, $email_message->raw_message);
     $email_message->load_address();
     $email_message->load_key($key);
     // If the feature is on but the post/pm function is not enabled, just log the message.
     if (empty($modSettings['pbe_post_enabled']) && empty($modSettings['pbe_pm_enabled'])) {
         return pbe_emailError('error_email_notenabled', $email_message);
     }
     // Spam I am?
     if ($email_message->load_spam() && !$force) {
         return pbe_emailError('error_found_spam', $email_message);
     }
     // Load the user from the database based on the sending email address
     $email_message->email['from'] = !empty($email_message->email['from']) ? strtolower($email_message->email['from']) : '';
     $pbe = query_load_user_info($email_message->email['from']);
     // Can't find this email in our database, a non-user, a spammer, a looser, a poser or even worse?
     if (empty($pbe)) {
         return pbe_emailError('error_not_find_member', $email_message);
     }
     // Find the message security key, without it we are not going anywhere ever
     if (empty($email_message->message_key_id)) {
         return pbe_emailError('error_missing_key', $email_message);
     }
     // Good we have a key, who was it sent to?
     $key_owner = query_key_owner($email_message->message_key_id);
     // Can't find this key in the database, either
     // a) spam attempt or b) replying with an expired/consumed key
     if (empty($key_owner) && !$force) {
         return pbe_emailError('error_' . ($email_message->message_type === 'p' ? 'pm_' : '') . 'not_find_entry', $email_message);
     }
     // The key received was not sent to this member ... how we love those email aggregators
     if (strtolower($key_owner) !== $email_message->email['from'] && !$force) {
         return pbe_emailError('error_key_sender_match', $email_message);
     }
     // In maintenance mode, just log it for now
     if (!empty($maintenance) && $maintenance !== 2 && !$pbe['user_info']['is_admin'] && !$user_info['is_admin']) {
         return pbe_emailError('error_in_maintenance_mode', $email_message);
     }
     // The email looks valid, now on to check the actual user trying to make the post/pm
     // lets load the topic/message info and any additional permissions we need
     if ($email_message->message_type === 't' || $email_message->message_type === 'm') {
         // Load the message/topic details
         $topic_info = query_load_message($email_message->message_type, $email_message->message_id, $pbe);
         if (empty($topic_info)) {
             return pbe_emailError('error_topic_gone', $email_message);
         }
         // Load board permissions
         query_load_permissions('board', $pbe, $topic_info);
     } else {
         // Load the PM details
         $pm_info = query_load_message($email_message->message_type, $email_message->message_id, $pbe);
         if (empty($pm_info)) {
             // Duh oh ... likely they deleted the PM on the site and are now
             // replying to the PM by email, the agony!
             return pbe_emailError('error_pm_not_found', $email_message);
         }
     }
     // Account for moderation actions
     pbe_check_moderation($pbe);
     // Maybe they want to do additional spam / security checking
     call_integration_hook('integrate_mailist_checks_before', array($email_message, $pbe));
     // Load in the correct Re: for the language
     if ($language === $pbe['user_info']['language']) {
         $pbe['response_prefix'] = $txt['response_prefix'];
     } else {
         loadLanguage('index', $language, false);
         $pbe['response_prefix'] = $txt['response_prefix'];
         loadLanguage('index');
     }
     // Allow for new topics to be started via a email subject change
     if (!empty($modSettings['maillist_newtopic_change']) && $email_message->message_type === 'm') {
         $subject = str_replace($pbe['response_prefix'], '', pbe_clean_email_subject($email_message->subject));
         $current_subject = str_replace($pbe['response_prefix'], '', $topic_info['subject']);
         // If it does not match, then we go to make a new topic instead
         if (trim($subject) != trim($current_subject)) {
             $board_info = query_load_board_details($topic_info['id_board'], $pbe);
             return pbe_create_topic($pbe, $email_message, $board_info);
         }
     }
     // Time to make a Post or a PM, first up topic and message replies
     if ($email_message->message_type === 't' || $email_message->message_type === 'm') {
         $result = pbe_create_post($pbe, $email_message, $topic_info);
     } elseif ($email_message->message_type === 'p') {
         $result = pbe_create_pm($pbe, $email_message, $pm_info);
     }
     if (!empty($result)) {
         // We have now posted or PM'ed .. lets do some database maintenance cause maintenance is fun :'(
         query_key_maintenance($email_message);
         // Update this user so the log shows they were/are active, no luking in the email ether
         query_update_member_stats($pbe, $email_message, $email_message->message_type === 'p' ? $pm_info : $topic_info);
     }
     return !empty($result);
 }
Exemple #2
0
/**
 * For a given type, t m or p, query the appropriate table for a given message id
 *
 * - If found returns the message subject
 *
 * @package Maillist
 * @param int $message_id
 * @param string $message_type
 * @param string $email
 */
function query_load_subject($message_id, $message_type, $email)
{
    $db = database();
    $subject = '';
    // Load up the core topic details,
    if ($message_type === 't') {
        $request = $db->query('', '
			SELECT
				t.id_topic, m.subject
			FROM {db_prefix}topics AS t
				INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
			WHERE t.id_topic = {int:id_topic}', array('id_topic' => $message_id));
    } elseif ($message_type === 'm') {
        $request = $db->query('', '
			SELECT
				m.id_topic, m.subject
			FROM {db_prefix}messages AS m
				INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic)
			WHERE m.id_msg = {int:message_id}', array('message_id' => $message_id));
    } elseif ($message_type === 'p') {
        // With PM's ... first get the member id based on the email
        $request = $db->query('', '
			SELECT
				id_member
			FROM {db_prefix}members
			WHERE email_address = {string:email}
				AND is_activated = {int:act}
			LIMIT 1', array('email' => $email, 'act' => 1));
        // Found them, now we find the PM to them with this ID
        if ($db->num_rows($request) !== 0) {
            list($id_member) = $db->fetch_row($request);
            $db->free_result($request);
            // Now find this PM ID and make sure it was sent to this member
            $request = $db->query('', '
				SELECT
					p.subject
				FROM {db_prefix}pm_recipients AS pmr, {db_prefix}personal_messages AS p
				WHERE pmr.id_pm = {int:id_pm}
					AND pmr.id_member = {int:id_member}
					AND p.id_pm = pmr.id_pm', array('id_member' => $id_member, 'id_pm' => $message_id));
        }
    }
    // If we found the message, topic or PM, return the subject
    if ($db->num_rows($request) != 0) {
        list($subject) = $db->fetch_row($request);
        $subject = pbe_clean_email_subject($subject);
    }
    $db->free_result($request);
    return $subject;
}