示例#1
0
/**
 * Moves a set of messages ($id) to another mailbox ($mailbox)
 * 
 * @param int    $imap_stream   The resource ID for the IMAP socket
 * @param mixed  $id            A string or array of messages to copy
 * @param string $mailbox       The destination mailbox
 * @param bool   $handle_errors Show error messages in case of a NO, BAD, or BYE response
 *
 * @return bool If move completed without error.
 *
 * @since 1.4.18
 *
 */
function sqimap_msgs_list_move($imap_stream, $id, $mailbox, $handle_errors = true)
{
    if (sqimap_msgs_list_copy($imap_stream, $id, $mailbox, $handle_errors)) {
        return sqimap_toggle_flag($imap_stream, $id, '\\Deleted', true, true);
    } else {
        return false;
    }
}
示例#2
0
/**
 * Deletes a message and move it to trash or expunge the mailbox
 * @param  resource imap connection
 * @param  string $mailbox mailbox, used for checking if it concerns the trash_folder
 * @param  array $id list with uid's
 * @param  bool   $bypass_trash (since 1.5.0) skip copy to trash
 * @return array  $aMessageList array with messages containing the new flags and UID @see parseFetch
 * @since 1.4.0
 */
function sqimap_msgs_list_delete($imap_stream, $mailbox, $id, $bypass_trash = false)
{
    // FIXME: Remove globals by introducing an associative array with properties as 4th argument as replacement for the $bypass_trash variable.
    global $move_to_trash, $trash_folder;
    if ($move_to_trash == true && $bypass_trash != true && (sqimap_mailbox_exists($imap_stream, $trash_folder) && $mailbox != $trash_folder)) {
        /**
         * turn off internal error handling (fourth argument = false) and
         * ignore copy to trash errors (allows to delete messages when overquota)
         */
        sqimap_msgs_list_copy($imap_stream, $id, $trash_folder, false);
    }
    return sqimap_toggle_flag($imap_stream, $id, '\\Deleted', true, true);
}
/**
 * Deletes a message and move it to trash or expunge the mailbox
 * @param  resource imap connection
 * @param  string $mailbox mailbox, used for checking if it concerns the trash_folder
 * @param  array $id list with uid's
 * @param  bool   $bypass_trash skip copy to trash
 * @return array  $aMessageList array with messages containing the new flags and UID @see parseFetch
 */
function sqimap_msgs_list_delete($imap_stream, $mailbox, $id, $bypass_trash = false)
{
    // FIX ME, remove globals by introducing an associative array with properties
    // as 4th argument as replacement for the bypass_trash var
    global $move_to_trash, $trash_folder;
    $bRes = true;
    if ($move_to_trash == true && $bypass_trash != true && (sqimap_mailbox_exists($imap_stream, $trash_folder) && $mailbox != $trash_folder)) {
        $bRes = sqimap_msgs_list_copy($imap_stream, $id, $trash_folder);
    }
    if ($bRes) {
        return sqimap_toggle_flag($imap_stream, $id, '\\Deleted', true, true);
    } else {
        return false;
    }
}
示例#4
0
    // undelete messages if user isn't using move_to_trash or auto_expunge
    // Removes \Deleted flag from selected messages
    if (count($id)) {
        sqimap_toggle_flag($imapConnection, $id, '\\Deleted', false, true);
    } else {
        $exception = true;
    }
} elseif (!isset($moveButton)) {
    if (count($id)) {
        $cnt = count($id);
        if (!isset($attache)) {
            if (isset($markRead)) {
                sqimap_toggle_flag($imapConnection, $id, '\\Seen', true, true);
            } else {
                if (isset($markUnread)) {
                    sqimap_toggle_flag($imapConnection, $id, '\\Seen', false, true);
                } else {
                    sqimap_msgs_list_delete($imapConnection, $mailbox, $id);
                    if ($auto_expunge) {
                        $cnt = sqimap_mailbox_expunge($imapConnection, $mailbox, true);
                    }
                    if ($startMessage + $cnt - 1 >= $mbx_response['EXISTS']) {
                        if ($startMessage > $show_num) {
                            $location = set_url_var($location, 'startMessage', $startMessage - $show_num, false);
                        } else {
                            $location = set_url_var($location, 'startMessage', 1, false);
                        }
                    }
                }
            }
        } else {
/**
 * Process messages list form and handle the cache gracefully. If $sButton and
 * $aUid are provided as argument then you can fake a message list submit and
 * use it i.e. in read_body.php for del move next and update the cache
 *
 * @param  resource $imapConnection imap connection
 * @param  array $aMailbox (reference) cached mailbox
 * @param  string $sButton fake a submit button
 * @param  array  $aUid    fake the $msg array
 * @return string $sError error string in case of an error
 * @author Marc Groot Koerkamp
 */
function handleMessageListForm($imapConnection, &$aMailbox, $sButton = '', $aUid = array())
{
    /* incoming formdata */
    $sButton = sqgetGlobalVar('moveButton', $sTmp, SQ_POST) ? 'move' : $sButton;
    $sButton = sqgetGlobalVar('expungeButton', $sTmp, SQ_POST) ? 'expunge' : $sButton;
    $sButton = sqgetGlobalVar('attache', $sTmp, SQ_POST) ? 'attache' : $sButton;
    $sButton = sqgetGlobalVar('delete', $sTmp, SQ_POST) ? 'setDeleted' : $sButton;
    $sButton = sqgetGlobalVar('undeleteButton', $sTmp, SQ_POST) ? 'setDeleted' : $sButton;
    $sButton = sqgetGlobalVar('markRead', $sTmp, SQ_POST) ? 'setSeen' : $sButton;
    $sButton = sqgetGlobalVar('markUnread', $sTmp, SQ_POST) ? 'unsetSeen' : $sButton;
    $sButton = sqgetGlobalVar('markFlagged', $sTmp, SQ_POST) ? 'setFlagged' : $sButton;
    $sButton = sqgetGlobalVar('markUnflagged', $sTmp, SQ_POST) ? 'unsetFlagged' : $sButton;
    sqgetGlobalVar('targetMailbox', $targetMailbox, SQ_POST);
    sqgetGlobalVar('bypass_trash', $bypass_trash, SQ_POST);
    sqgetGlobalVar('msg', $msg, SQ_POST);
    $sError = '';
    $mailbox = $aMailbox['NAME'];
    /* retrieve the check boxes */
    $aUid = isset($msg) && is_array($msg) ? array_values($msg) : $aUid;
    if (count($aUid) && $sButton != 'expunge') {
        $aUpdatedMsgs = false;
        $bExpunge = false;
        switch ($sButton) {
            case 'setDeleted':
                // check if id exists in case we come from read_body
                if (count($aUid) == 1 && is_array($aMailbox['UIDSET'][$aMailbox['SETINDEX']]) && !in_array($aUid[0], $aMailbox['UIDSET'][$aMailbox['SETINDEX']])) {
                    break;
                }
                $aUpdatedMsgs = sqimap_msgs_list_delete($imapConnection, $mailbox, $aUid, $bypass_trash);
                $bExpunge = true;
                break;
            case 'unsetDeleted':
            case 'setSeen':
            case 'unsetSeen':
            case 'setFlagged':
            case 'unsetFlagged':
                // get flag
                $sFlag = substr($sButton, 0, 3) == 'set' ? '\\' . substr($sButton, 3) : '\\' . substr($sButton, 5);
                $bSet = substr($sButton, 0, 3) == 'set' ? true : false;
                $aUpdatedMsgs = sqimap_toggle_flag($imapConnection, $aUid, $sFlag, $bSet, true);
                break;
            case 'move':
                $aUpdatedMsgs = sqimap_msgs_list_move($imapConnection, $aUid, $targetMailbox);
                sqsession_register($targetMailbox, 'lastTargetMailbox');
                $bExpunge = true;
                break;
            case 'attache':
                $aMsgHeaders = array();
                foreach ($aUid as $iUid) {
                    $aMsgHeaders[$iUid] = $aMailbox['MSG_HEADERS'][$iUid];
                }
                if (count($aMsgHeaders)) {
                    $composesession = attachSelectedMessages($imapConnection, $aMsgHeaders);
                    // dirty hack, add info to $aMailbox
                    $aMailbox['FORWARD_SESSION'] = $composesession;
                }
                break;
            default:
                // Hook for plugin buttons
                do_hook_function('mailbox_display_button_action', $aUid);
                break;
        }
        /**
         * Updates messages is an array containing the result of the untagged
         * fetch responses send by the imap server due to a flag change. That
         * response is parsed in a array with msg arrays by the parseFetch function
         */
        if ($aUpdatedMsgs) {
            // Update the message headers cache
            $aDeleted = array();
            foreach ($aUpdatedMsgs as $iUid => $aMsg) {
                if (isset($aMsg['FLAGS'])) {
                    /**
                     * Only update the cached headers if the header is
                     * cached.
                     */
                    if (isset($aMailbox['MSG_HEADERS'][$iUid])) {
                        $aMailbox['MSG_HEADERS'][$iUid]['FLAGS'] = $aMsg['FLAGS'];
                    }
                    /**
                     * Count the messages with the \Delete flag set so we can determine
                     * if the number of expunged messages equals the number of flagged
                     * messages for deletion.
                     */
                    if (isset($aMsg['FLAGS']['\\deleted']) && $aMsg['FLAGS']['\\deleted']) {
                        $aDeleted[] = $iUid;
                    }
                }
            }
            if ($bExpunge && $aMailbox['AUTO_EXPUNGE'] && ($iExpungedMessages = sqimap_mailbox_expunge($imapConnection, $aMailbox['NAME'], true))) {
                if (count($aDeleted) != $iExpungedMessages) {
                    // there are more messages deleted permanently then we expected
                    // invalidate the cache
                    $aMailbox['UIDSET'][$aMailbox['SETINDEX']] = false;
                    $aMailbox['MSG_HEADERS'] = false;
                } else {
                    // remove expunged messages from cache
                    $aUidSet = $aMailbox['UIDSET'][$aMailbox['SETINDEX']];
                    if (is_array($aUidSet)) {
                        // create a UID => array index temp array
                        $aUidSetDummy = array_flip($aUidSet);
                        foreach ($aDeleted as $iUid) {
                            // get the id as well in case of SQM_SORT_NONE
                            if ($aMailbox['SORT'] == SQSORT_NONE) {
                                $aMailbox['ID'] = false;
                                //$iId = $aMailbox['MSG_HEADERS'][$iUid]['ID'];
                                //unset($aMailbox['ID'][$iId]);
                            }
                            // unset the UID and message header
                            unset($aUidSetDummy[$iUid]);
                            unset($aMailbox['MSG_HEADERS'][$iUid]);
                        }
                        $aMailbox['UIDSET'][$aMailbox['SETINDEX']] = array_keys($aUidSetDummy);
                    }
                }
                // update EXISTS info
                if ($iExpungedMessages) {
                    $aMailbox['EXISTS'] -= (int) $iExpungedMessages;
                }
                // Change the startMessage number if the mailbox was changed
                if ($aMailbox['PAGEOFFSET'] - 1 >= $aMailbox['EXISTS']) {
                    $aMailbox['PAGEOFFSET'] = $aMailbox['PAGEOFFSET'] > $aMailbox['LIMIT'] ? $aMailbox['PAGEOFFSET'] - $aMailbox['LIMIT'] : 1;
                    $aMailbox['OFFSET'] = $aMailbox['PAGEOFFSET'] - 1;
                }
            }
        }
    } else {
        if ($sButton == 'expunge') {
            /**
             * on expunge we do not know which messages will be deleted
             * so it's useless to try to sync the cache
             * Close the mailbox so we do not need to parse the untagged expunge
             * responses which do not contain uid info.
             * NB: Closing a mailbox is faster then expunge because the imap
             * server does not need to generate the untagged expunge responses
             */
            sqimap_run_command($imapConnection, 'CLOSE', false, $result, $message);
            $aMbxResponse = sqimap_mailbox_select($imapConnection, $aMailbox['NAME']);
            // update the $aMailbox array
            $aMailbox['EXISTS'] = $aMbxResponse['EXISTS'];
            $aMailbox['UIDSET'] = false;
        } else {
            if ($sButton) {
                $sError = _("No messages were selected.");
            }
        }
    }
    return $sError;
}
示例#6
0
/**
 * Process messages list form and handle the cache gracefully. If $sButton and
 * $aUid are provided as argument then you can fake a message list submit and
 * use it i.e. in read_body.php for del move next and update the cache
 *
 * @param  resource $imapConnection imap connection
 * @param  array    $aMailbox       (reference) cached mailbox
 * @param  string   $sButton        fake a submit button
 * @param  array    $aUid           fake the $msg array
 * @param  string   $targetMailbox  fake the target mailbox for move operations
 * @param  boolean  $bypass_trash   fake the bypass trash checkbox for delete operations
 * @return string $sError error string in case of an error
 * @since 1.5.1
 * @author Marc Groot Koerkamp
 */
function handleMessageListForm($imapConnection, &$aMailbox, $sButton = '', $aUid = array(), $targetMailbox = '', $bypass_trash = NULL)
{
    /* incoming formdata */
    $sButton = sqgetGlobalVar('moveButton', $sTmp, SQ_FORM) ? 'move' : $sButton;
    $sButton = sqgetGlobalVar('copyButton', $sTmp, SQ_FORM) ? 'copy' : $sButton;
    $sButton = sqgetGlobalVar('expungeButton', $sTmp, SQ_FORM) ? 'expunge' : $sButton;
    $sButton = sqgetGlobalVar('forward', $sTmp, SQ_FORM) ? 'forward' : $sButton;
    $sButton = sqgetGlobalVar('delete', $sTmp, SQ_FORM) ? 'setDeleted' : $sButton;
    $sButton = sqgetGlobalVar('undeleteButton', $sTmp, SQ_FORM) ? 'unsetDeleted' : $sButton;
    $sButton = sqgetGlobalVar('markRead', $sTmp, SQ_FORM) ? 'setSeen' : $sButton;
    $sButton = sqgetGlobalVar('markUnread', $sTmp, SQ_FORM) ? 'unsetSeen' : $sButton;
    $sButton = sqgetGlobalVar('markFlagged', $sTmp, SQ_FORM) ? 'setFlagged' : $sButton;
    $sButton = sqgetGlobalVar('markUnflagged', $sTmp, SQ_FORM) ? 'unsetFlagged' : $sButton;
    if (empty($targetMailbox)) {
        sqgetGlobalVar('targetMailbox', $targetMailbox, SQ_FORM);
    }
    if (is_null($bypass_trash)) {
        sqgetGlobalVar('bypass_trash', $bypass_trash, SQ_FORM);
    }
    sqgetGlobalVar('msg', $msg, SQ_FORM);
    if (sqgetGlobalVar('account', $iAccount, SQ_FORM) === false) {
        $iAccount = 0;
    }
    $sError = '';
    $mailbox = $aMailbox['NAME'];
    /* retrieve the check boxes */
    $aUid = isset($msg) && is_array($msg) ? array_values($msg) : $aUid;
    if (count($aUid) && $sButton != 'expunge') {
        // don't do anything to any messages until we have done security check
        // FIXME: not sure this code really belongs here, but there's nowhere else to put it with this architecture
        sqgetGlobalVar('smtoken', $submitted_token, SQ_FORM, '');
        sm_validate_security_token($submitted_token, -1, TRUE);
        // make sure message UIDs are sanitized (BIGINT)
        foreach ($aUid as $i => $uid) {
            $aUid[$i] = preg_match('/^[0-9]+$/', $uid) ? $uid : '0';
        }
        $aUpdatedMsgs = false;
        $bExpunge = false;
        switch ($sButton) {
            case 'setDeleted':
                // check if id exists in case we come from read_body
                if (count($aUid) == 1 && is_array($aMailbox['UIDSET'][$aMailbox['SETINDEX']]) && !in_array($aUid[0], $aMailbox['UIDSET'][$aMailbox['SETINDEX']])) {
                    break;
                }
                $aUpdatedMsgs = sqimap_msgs_list_delete($imapConnection, $mailbox, $aUid, $bypass_trash);
                $bExpunge = true;
                //}
                break;
            case 'unsetDeleted':
            case 'setSeen':
            case 'unsetSeen':
            case 'setFlagged':
            case 'unsetFlagged':
                // get flag
                $sFlag = substr($sButton, 0, 3) == 'set' ? '\\' . substr($sButton, 3) : '\\' . substr($sButton, 5);
                $bSet = substr($sButton, 0, 3) == 'set' ? true : false;
                $aUpdatedMsgs = sqimap_toggle_flag($imapConnection, $aUid, $sFlag, $bSet, true);
                break;
            case 'move':
                $aUpdatedMsgs = sqimap_msgs_list_move($imapConnection, $aUid, $targetMailbox, true, $mailbox);
                sqsession_register($targetMailbox, 'lastTargetMailbox');
                $bExpunge = true;
                break;
            case 'copy':
                // sqimap_msgs_list_copy returns true or false.
                // If error happens - fourth argument handles it inside function.
                sqimap_msgs_list_copy($imapConnection, $aUid, $targetMailbox, true);
                sqsession_register($targetMailbox, 'lastTargetMailbox');
                break;
            case 'forward':
                $aMsgHeaders = array();
                foreach ($aUid as $iUid) {
                    $aMsgHeaders[$iUid] = $aMailbox['MSG_HEADERS'][$iUid];
                }
                if (count($aMsgHeaders)) {
                    $composesession = attachSelectedMessages($imapConnection, $aMsgHeaders);
                    // dirty hack, add info to $aMailbox
                    $aMailbox['FORWARD_SESSION']['SESSION_NUMBER'] = $composesession;
                    $aMailbox['FORWARD_SESSION']['UIDS'] = $aUid;
                }
                break;
            default:
                // Hook for plugin buttons
                $temp = array(&$sButton, &$aMailbox, $iAccount, $aMailbox['NAME'], &$aUid);
                do_hook('mailbox_display_button_action', $temp);
                break;
        }
        /**
         * $aUpdatedMsgs is an array containing the result of the untagged
         * fetch responses send by the imap server due to a flag change. That
         * response is parsed in an array with msg arrays by the parseFetch function
         */
        if ($aUpdatedMsgs) {
            // Update the message headers cache
            $aDeleted = array();
            foreach ($aUpdatedMsgs as $iUid => $aMsg) {
                if (isset($aMsg['FLAGS'])) {
                    /**
                     * Only update the cached headers if the header is
                     * cached.
                     */
                    if (isset($aMailbox['MSG_HEADERS'][$iUid])) {
                        $aMailbox['MSG_HEADERS'][$iUid]['FLAGS'] = $aMsg['FLAGS'];
                    }
                    /**
                     * Also update flags in message object
                     */
                    //FIXME: WHY are we keeping flags in TWO places?!?  This is error-prone and some core code uses the is_xxxx message object values while other code uses the flags array above.  That's a mess.
                    if (isset($aMailbox['MSG_HEADERS'][$iUid]['MESSAGE_OBJECT'])) {
                        $message = $aMailbox['MSG_HEADERS'][$iUid]['MESSAGE_OBJECT'];
                        $message->is_seen = false;
                        $message->is_answered = false;
                        $message->is_forwarded = false;
                        $message->is_deleted = false;
                        $message->is_flagged = false;
                        $message->is_mdnsent = false;
                        foreach ($aMsg['FLAGS'] as $flag => $value) {
                            if (strtolower($flag) == '\\seen' && $value) {
                                $message->is_seen = true;
                            } else {
                                if (strtolower($flag) == '\\answered' && $value) {
                                    $message->is_answered = true;
                                } else {
                                    if (strtolower($flag) == '$forwarded' && $value) {
                                        $message->is_forwarded = true;
                                    } else {
                                        if (strtolower($flag) == '\\deleted' && $value) {
                                            $message->is_deleted = true;
                                        } else {
                                            if (strtolower($flag) == '\\flagged' && $value) {
                                                $message->is_flagged = true;
                                            } else {
                                                if (strtolower($flag) == '$mdnsent' && $value) {
                                                    $message->is_mdnsent = true;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        $aMailbox['MSG_HEADERS'][$iUid]['MESSAGE_OBJECT'] = $message;
                    }
                    /**
                     * Count the messages with the \Delete flag set so we can determine
                     * if the number of expunged messages equals the number of flagged
                     * messages for deletion.
                     */
                    if (isset($aMsg['FLAGS']['\\deleted']) && $aMsg['FLAGS']['\\deleted']) {
                        $aDeleted[] = $iUid;
                    }
                }
            }
            if ($bExpunge && $aMailbox['AUTO_EXPUNGE'] && ($iExpungedMessages = sqimap_mailbox_expunge($imapConnection, $aMailbox['NAME'], true))) {
                if (count($aDeleted) != $iExpungedMessages) {
                    // there are more messages deleted permanently then we expected
                    // invalidate the cache
                    $aMailbox['UIDSET'][$aMailbox['SETINDEX']] = false;
                    $aMailbox['MSG_HEADERS'] = false;
                } else {
                    // remove expunged messages from cache
                    $aUidSet = $aMailbox['UIDSET'][$aMailbox['SETINDEX']];
                    if (is_array($aUidSet)) {
                        // create a UID => array index temp array
                        $aUidSetDummy = array_flip($aUidSet);
                        foreach ($aDeleted as $iUid) {
                            // get the id as well in case of SQM_SORT_NONE
                            if ($aMailbox['SORT'] == SQSORT_NONE) {
                                $aMailbox['ID'] = false;
                                //$iId = $aMailbox['MSG_HEADERS'][$iUid]['ID'];
                                //unset($aMailbox['ID'][$iId]);
                            }
                            // unset the UID and message header
                            unset($aUidSetDummy[$iUid]);
                            unset($aMailbox['MSG_HEADERS'][$iUid]);
                        }
                        $aMailbox['UIDSET'][$aMailbox['SETINDEX']] = array_keys($aUidSetDummy);
                    }
                }
                // update EXISTS info
                if ($iExpungedMessages) {
                    $aMailbox['EXISTS'] -= (int) $iExpungedMessages;
                    $aMailbox['TOTAL'][$aMailbox['SETINDEX']] -= (int) $iExpungedMessages;
                }
                if ($aMailbox['PAGEOFFSET'] - 1 >= $aMailbox['EXISTS']) {
                    $aMailbox['PAGEOFFSET'] = $aMailbox['PAGEOFFSET'] > $aMailbox['LIMIT'] ? $aMailbox['PAGEOFFSET'] - $aMailbox['LIMIT'] : 1;
                    $aMailbox['OFFSET'] = $aMailbox['PAGEOFFSET'] - 1;
                }
            }
        }
    } else {
        if ($sButton == 'expunge') {
            /**
             * on expunge we do not know which messages will be deleted
             * so it's useless to try to sync the cache
             *
             * Close the mailbox so we do not need to parse the untagged expunge
             * responses which do not contain uid info.
             * NB: Closing a mailbox is faster then expunge because the imap
             * server does not need to generate the untagged expunge responses
             */
            sqimap_run_command($imapConnection, 'CLOSE', false, $result, $message);
            $aMailbox = sqm_api_mailbox_select($imapConnection, $iAccount, $aMailbox['NAME'], array(), array());
        } else {
            // this is the same hook as above, but here it is called in the
            // context of not having had any messages selected and if any
            // plugin handles the situation, it should return TRUE so we
            // know this was not an erroneous user action
            //
            global $null;
            $temp = array(&$sButton, &$aMailbox, $iAccount, $aMailbox['NAME'], $null);
            if (!boolean_hook_function('mailbox_display_button_action', $temp, 1) && $sButton) {
                $sError = _("No messages were selected.");
            }
        }
    }
    return $sError;
}
function bayesspam_get_tokens(&$imap_stream, $passed_id)
{
    if ($GLOBALS['bayesdbhandle'] == null) {
        return;
    }
    $tokens = array();
    $headers = sqimap_get_small_header_list($imap_stream, array($passed_id));
    $version_array = split('\\.', $GLOBALS['version']);
    bayesspam_set_message_id($imap_stream, $passed_id);
    $lines1 = sqimap_run_command($imap_stream, 'FETCH ' . $passed_id . ':' . $passed_id . ' BODY[HEADER]<0.' . $GLOBALS['bayesspam_scan_size'] . '>', true, $response, $msg, $GLOBALS['uid_support']);
    $response = array_shift($lines1);
    preg_match('/\\{(\\d+)\\}/', $response, $matches);
    $lines2 = sqimap_run_command($imap_stream, 'FETCH ' . $passed_id . ':' . $passed_id . ' BODY[TEXT]<0.' . ($GLOBALS['bayesspam_scan_size'] - $matches[1]) . '>', true, $response, $msg, $GLOBALS['uid_support']);
    if ($version_array[0] == 1 && $version_array[1] <= 2) {
        if (!$headers[0]['FLAG_SEEN']) {
            sqimap_messages_remove_flag($imap_stream, $passed_id, $passed_id, 'Seen');
        }
    } else {
        if ($version_array[0] == 1 && $version_array[1] == 5) {
            if (!isset($headers[$passed_id]['FLAGS']['\\seen'])) {
                sqimap_toggle_flag($imap_stream, $passed_id, '\\Seen', FALSE, TRUE);
            }
        } else {
            if (!$headers[0]['FLAG_SEEN']) {
                sqimap_messages_remove_flag($imap_stream, $passed_id, $passed_id, 'Seen', FALSE);
            }
        }
    }
    array_shift($lines2);
    $lines = array_merge($lines1, $lines2);
    $hdr_lines = count($lines1);
    unset($lines1);
    unset($lines2);
    $mime = '';
    $encoding = '';
    $decoded = '';
    $content_type = '';
    $in_html_tag = 0;
    for ($i = 0; $i < count($lines); $i++) {
        $line = $lines[$i];
        if ($line == '') {
            continue;
        }
        if ($mime != '' && preg_match('/' . $mime . '/', $line)) {
            $encoding = '';
            continue;
        }
        if (preg_match('/base64/i', $encoding)) {
            $decoded = '';
            while (preg_match('/^([A-Za-z0-9+\\/]{4}){1,48}[\\n\\r]*/', $line) || preg_match('/^[A-Za-z0-9+\\/]+=+?[\\n\\r]*/', $line)) {
                $decoded .= base64_decode($line);
                if (preg_match('/[^a-zA-Z\\-\\.]$/', $decoded)) {
                    $temp_tokens = bayesspam_parse_line($decoded, 'ENCODED');
                    foreach ($temp_tokens as $token) {
                        $tokens[] = $token;
                    }
                    $decoded = '';
                }
                $i++;
                if ($i < count($lines)) {
                    $line = $lines[$i];
                } else {
                    break;
                }
            }
            $temp_tokens = bayesspam_parse_line($decoded, 'ENCODED');
            foreach ($temp_tokens as $token) {
                $tokens[] = $token;
            }
        }
        if ($i == count($lines)) {
            break;
        }
        if (preg_match('/<html>/i', $line)) {
            $content_type = 'text/html';
        }
        if (preg_match('/quoted\\-printable/', $encoding)) {
            $line = preg_replace('/=[\\r\\n]*$/', "=\n", $line);
            while (preg_match('/=\\n$/', $line)) {
                $tokens[] = 'CHEATER: Line Break';
                $i++;
                $line = preg_replace('/=\\n$/', '', $line);
                $line = $line . $lines[$i];
            }
            $line = quoted_printable_decode($line);
        }
        $oldline = $line;
        while ($oldline != ($line = preg_replace('/<!--.*?-->/', '', $line))) {
            $tokens[] = 'HTML: CHEATER';
            $oldline = $line;
        }
        unset($oldline);
        if (preg_match('/html/', $content_type)) {
            if ($in_html_tag) {
                if (preg_match('/(.*?)>/', $line, $matches)) {
                    $line = preg_replace('/(.*?)>/', ' ', $line);
                    $html_arg .= $matches[1];
                    $in_html_tag = 0;
                    if (preg_match('/quoted\\-printable/', $line)) {
                        $html_tag = preg_replace('/=\\n ?/', '', $html_tag);
                        $html_arg = preg_replace('/=\\n ?/', '', $html_arg);
                    }
                    $tokens[] = bayesspam_parse_html_tag($html_tag, $html_arg);
                    $tokens[] = 'HTMLTAG: ' . $html_tag;
                    $html_tag = '';
                    $html_arg = '';
                } else {
                    $html_arg .= ' ' . $line;
                    $line = '';
                    continue;
                }
            }
            while (preg_match('/<[\\/]?([A-Za-z]+)([^>]*?)>/', $line, $matches)) {
                $line = preg_replace('/<[\\/]?([A-Za-z]+)([^>]*?)>/', '', $line, 1);
                $tokens[] = bayesspam_parse_html_tag($matches[1], $matches[2]);
                $tokens[] = 'HTMLTAG: ' . $matches[1];
            }
            if (preg_match('/<([^ >]+)([^>]*)$/', $line, $matches)) {
                $line = preg_replace('/<([^ >]+)([^>]*)$/', '', $line);
                $html_tag = $matches[1];
                $html_arg = $matches[2];
                $in_html_tag = 1;
            }
        }
        if (preg_match('/^([A-Za-z-]+): ?([^\\n\\r]*)/', $line, $matches)) {
            $header = $matches[1];
            $arguement = $matches[2];
            $tokens[] = 'HEADERTYPE: ' . $header;
            if (preg_match('/(From|To|Cc)/i', $header)) {
                if (preg_match('/From/i', $header)) {
                    $encoding = '';
                    $content_type = '';
                }
                while (preg_match('/<([a-zA-Z0-9\\-_\\.]+?@([a-zA-Z0-9\\-_\\.]+?))>/', $arguement, $matches)) {
                    $arguement = preg_replace('/<[a-zA-Z0-9\\-_\\.]+?@[a-zA-Z0-9\\-_\\.]+?>/', '', $arguement, 1);
                    if ($matches[1]) {
                        $tokens[] = 'EMAIL: ' . $matches[1];
                    }
                    if ($matches[2]) {
                        $tokens[] = 'DOMAIN: ' . $matches[2];
                    }
                }
                while (preg_match('/([a-zA-Z0-9\\-_\\.]+?@([a-zA-Z0-9\\-_\\.]+))/', $arguement, $matches)) {
                    $arguement = preg_replace('/([a-zA-Z0-9\\-_\\.]+?@([a-zA-Z0-9\\-_\\.]+))/', '', $arguement);
                    if ($matches[1]) {
                        $tokens[] = 'EMAIL: ' . $matches[1];
                    }
                    if ($matches[2]) {
                        $tokens[] = 'DOMAIN: ' . $matches[2];
                    }
                }
                $temp_tokens = bayesspam_parse_line($arguement, 'HEADER');
                foreach ($temp_tokens as $token) {
                    $tokens[] = $token;
                }
                continue;
            }
            if (preg_match('/Subject/i', $header)) {
                $temp_tokens = bayesspam_parse_line($arguement, 'SUBJECT');
                foreach ($temp_tokens as $token) {
                    $tokens[] = $token;
                }
                continue;
            }
            if (preg_match('/Content-Type/i', $header)) {
                if (preg_match('/multipart\\//i', $arguement)) {
                    $boundary = $arguement;
                    if (preg_match('/boundary="(.*)"/', $arguement)) {
                        $i++;
                        $boundary = $lines[$i];
                    }
                    if (preg_match('/boundary="(.*)"/', $boundary, $matches)) {
                        $mime = $matches[1];
                        $mime = preg_replace('/(\\+|\\/|\\?|\\*|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\^|\\$|\\.)/', $matches[1], $mime);
                    }
                }
                $content_type = $arguement;
                continue;
            }
            if (preg_match('/Content-Transfer-Encoding/i', $header)) {
                $encoding = $arguement;
                continue;
            }
            if (preg_match('/X-Text-Classification/', $header)) {
                $tokens[] = 'TEXTCLASS: ' . $arguement;
                continue;
            }
            if (preg_match('/(Thread-Index|X-UIDL|Message-ID|X-Text-Classification|X-Mime-Key)/i', $header)) {
                continue;
            }
            $temp_tokens = bayesspam_parse_line($arguement, 'HEADER');
            foreach ($temp_tokens as $token) {
                $tokens[] = $token;
            }
        } else {
            if ($i < $hdr_lines) {
                $temp_tokens = bayesspam_parse_line($arguement, 'HEADER');
            } else {
                $temp_tokens = bayesspam_parse_line($arguement, 'BODY');
            }
            foreach ($temp_tokens as $token) {
                $tokens[] = $token;
            }
        }
    }
    return $tokens;
}
示例#8
0
/**
 * temporary function to make use of the deliver class.
 * In the future the responsible backend should be automaticly loaded
 * and conf.pl should show a list of available backends.
 * The message also should be constructed by the message class.
 *
 * @param object $composeMessage The message being sent.  Please note
 *                               that it is passed by reference and
 *                               will be returned modified, with additional
 *                               headers, such as Message-ID, Date, In-Reply-To,
 *                               References, and so forth.
 *
 * @return boolean FALSE if delivery failed, or some non-FALSE value
 *                 upon success.
 *
 */
function deliverMessage(&$composeMessage, $draft = false)
{
    global $send_to, $send_to_cc, $send_to_bcc, $mailprio, $subject, $body, $username, $identity, $idents, $data_dir, $request_mdn, $request_dr, $default_charset, $useSendmail, $domain, $action, $default_move_to_sent, $move_to_sent, $imapServerAddress, $imapPort, $imap_stream_options, $sent_folder, $key;
    $rfc822_header = $composeMessage->rfc822_header;
    $abook = addressbook_init(false, true);
    $rfc822_header->to = $rfc822_header->parseAddress($send_to, true, array(), '', $domain, array(&$abook, 'lookup'));
    $rfc822_header->cc = $rfc822_header->parseAddress($send_to_cc, true, array(), '', $domain, array(&$abook, 'lookup'));
    $rfc822_header->bcc = $rfc822_header->parseAddress($send_to_bcc, true, array(), '', $domain, array(&$abook, 'lookup'));
    $rfc822_header->priority = $mailprio;
    $rfc822_header->subject = $subject;
    $special_encoding = '';
    if (strtolower($default_charset) == 'iso-2022-jp') {
        if (mb_detect_encoding($body) == 'ASCII') {
            $special_encoding = '8bit';
        } else {
            $body = mb_convert_encoding($body, 'JIS');
            $special_encoding = '7bit';
        }
    }
    $composeMessage->setBody($body);
    $reply_to = '';
    $reply_to = $idents[$identity]['reply_to'];
    if ($reply_to && strpos($reply_to, '@') === FALSE) {
        $reply_to .= '@' . $domain;
    }
    $from_addr = build_from_header($identity);
    $rfc822_header->from = $rfc822_header->parseAddress($from_addr, true);
    if ($reply_to) {
        $rfc822_header->reply_to = $rfc822_header->parseAddress($reply_to, true);
    }
    /* Receipt: On Read */
    if (isset($request_mdn) && $request_mdn) {
        $rfc822_header->dnt = $rfc822_header->parseAddress($from_addr, true);
    } elseif (isset($rfc822_header->dnt)) {
        unset($rfc822_header->dnt);
    }
    /* Receipt: On Delivery */
    if (!empty($request_dr)) {
        //FIXME: it would be better to fiddle with headers inside of the message object or possibly when delivering the message to its destination; is this possible?
        $rfc822_header->more_headers['Return-Receipt-To'] = $from_addr;
    } elseif (isset($rfc822_header->more_headers['Return-Receipt-To'])) {
        unset($rfc822_header->more_headers['Return-Receipt-To']);
    }
    /* multipart messages */
    if (count($composeMessage->entities)) {
        $message_body = new Message();
        $message_body->body_part = $composeMessage->body_part;
        $composeMessage->body_part = '';
        $mime_header = new MessageHeader();
        $mime_header->type0 = 'text';
        $mime_header->type1 = 'plain';
        if ($special_encoding) {
            $mime_header->encoding = $special_encoding;
        } else {
            $mime_header->encoding = '8bit';
        }
        if ($default_charset) {
            $mime_header->parameters['charset'] = $default_charset;
        }
        $message_body->mime_header = $mime_header;
        array_unshift($composeMessage->entities, $message_body);
        $content_type = new ContentType('multipart/mixed');
    } else {
        $content_type = new ContentType('text/plain');
        if ($special_encoding) {
            $rfc822_header->encoding = $special_encoding;
        } else {
            $rfc822_header->encoding = '8bit';
        }
        if ($default_charset) {
            $content_type->properties['charset'] = $default_charset;
        }
    }
    $rfc822_header->content_type = $content_type;
    $composeMessage->rfc822_header = $rfc822_header;
    if ($action == 'reply' || $action == 'reply_all') {
        global $passed_id, $passed_ent_id;
        $reply_id = $passed_id;
        $reply_ent_id = $passed_ent_id;
    } else {
        $reply_id = '';
        $reply_ent_id = '';
    }
    /* Here you can modify the message structure just before we hand
       it over to deliver; plugin authors note that $composeMessage
       is sent and modified by reference since 1.5.2 */
    do_hook('compose_send', $composeMessage);
    if (!$useSendmail && !$draft) {
        require_once SM_PATH . 'class/deliver/Deliver_SMTP.class.php';
        $deliver = new Deliver_SMTP();
        global $smtpServerAddress, $smtpPort, $smtp_stream_options, $pop_before_smtp, $pop_before_smtp_host;
        $authPop = isset($pop_before_smtp) && $pop_before_smtp ? true : false;
        if (empty($pop_before_smtp_host)) {
            $pop_before_smtp_host = $smtpServerAddress;
        }
        get_smtp_user($user, $pass);
        $stream = $deliver->initStream($composeMessage, $domain, 0, $smtpServerAddress, $smtpPort, $user, $pass, $authPop, $pop_before_smtp_host, $smtp_stream_options);
    } elseif (!$draft) {
        require_once SM_PATH . 'class/deliver/Deliver_SendMail.class.php';
        global $sendmail_path, $sendmail_args;
        // Check for outdated configuration
        if (!isset($sendmail_args)) {
            if ($sendmail_path == '/var/qmail/bin/qmail-inject') {
                $sendmail_args = '';
            } else {
                $sendmail_args = '-i -t';
            }
        }
        $deliver = new Deliver_SendMail(array('sendmail_args' => $sendmail_args));
        $stream = $deliver->initStream($composeMessage, $sendmail_path);
    } elseif ($draft) {
        global $draft_folder;
        $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, 0, $imap_stream_options);
        if (sqimap_mailbox_exists($imap_stream, $draft_folder)) {
            require_once SM_PATH . 'class/deliver/Deliver_IMAP.class.php';
            $imap_deliver = new Deliver_IMAP();
            $success = $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id, $imap_stream, $draft_folder);
            sqimap_logout($imap_stream);
            unset($imap_deliver);
            $composeMessage->purgeAttachments();
            return $success;
        } else {
            $msg = '<br />' . sprintf(_("Error: Draft folder %s does not exist."), sm_encode_html_special_chars($draft_folder));
            plain_error_message($msg);
            return false;
        }
    }
    $success = false;
    if ($stream) {
        $deliver->mail($composeMessage, $stream, $reply_id, $reply_ent_id);
        $success = $deliver->finalizeStream($stream);
    }
    if (!$success) {
        // $deliver->dlv_server_msg is not always server's reply
        $msg = _("Message not sent.") . "<br />\n" . (isset($deliver->dlv_msg) ? $deliver->dlv_msg : '');
        if (!empty($deliver->dlv_server_msg)) {
            // add 'server replied' part only when it is not empty.
            // Delivery error can be generated by delivery class itself
            $msg .= '<br />' . _("Server replied:") . ' ' . (isset($deliver->dlv_ret_nr) ? $deliver->dlv_ret_nr . ' ' : '') . nl2br(sm_encode_html_special_chars($deliver->dlv_server_msg));
        }
        plain_error_message($msg);
    } else {
        unset($deliver);
        $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, 0, $imap_stream_options);
        // mark as replied or forwarded if applicable
        //
        global $what, $iAccount, $startMessage, $passed_id, $fwduid, $mailbox;
        if ($action == 'reply' || $action == 'reply_all' || $action == 'forward' || $action == 'forward_as_attachment') {
            require SM_PATH . 'functions/mailbox_display.php';
            $aMailbox = sqm_api_mailbox_select($imap_stream, $iAccount, $mailbox, array('setindex' => $what, 'offset' => $startMessage), array());
            switch ($action) {
                case 'reply':
                case 'reply_all':
                    // check if we are allowed to set the \\Answered flag
                    if (in_array('\\answered', $aMailbox['PERMANENTFLAGS'], true)) {
                        $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, array($passed_id), '\\Answered', true, false);
                        if (isset($aUpdatedMsgs[$passed_id]['FLAGS'])) {
                            /**
                             * Only update the cached headers if the header is
                             * cached.
                             */
                            if (isset($aMailbox['MSG_HEADERS'][$passed_id])) {
                                $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'] = $aMsg['FLAGS'];
                            }
                        }
                    }
                    break;
                case 'forward':
                case 'forward_as_attachment':
                    // check if we are allowed to set the $Forwarded flag (RFC 4550 paragraph 2.8)
                    if (in_array('$forwarded', $aMailbox['PERMANENTFLAGS'], true) || in_array('\\*', $aMailbox['PERMANENTFLAGS'])) {
                        // when forwarding as an attachment from the message
                        // list, passed_id is not used, need to get UID(s)
                        // from the query string
                        //
                        if (empty($passed_id) && !empty($fwduid)) {
                            $ids = explode('_', $fwduid);
                        } else {
                            $ids = array($passed_id);
                        }
                        $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, $ids, '$Forwarded', true, false);
                        foreach ($ids as $id) {
                            if (isset($aUpdatedMsgs[$id]['FLAGS'])) {
                                if (isset($aMailbox['MSG_HEADERS'][$id])) {
                                    $aMailbox['MSG_HEADERS'][$id]['FLAGS'] = $aMsg['FLAGS'];
                                }
                            }
                        }
                    }
                    break;
            }
            /**
             * Write mailbox with updated seen flag information back to cache.
             */
            if (isset($aUpdatedMsgs[$passed_id])) {
                $mailbox_cache[$iAccount . '_' . $aMailbox['NAME']] = $aMailbox;
                sqsession_register($mailbox_cache, 'mailbox_cache');
            }
        }
        // move to sent folder
        //
        $move_to_sent = getPref($data_dir, $username, 'move_to_sent');
        if (isset($default_move_to_sent) && $default_move_to_sent != 0) {
            $svr_allow_sent = true;
        } else {
            $svr_allow_sent = false;
        }
        if (isset($sent_folder) && ($sent_folder != '' || $sent_folder != 'none') && sqimap_mailbox_exists($imap_stream, $sent_folder)) {
            $fld_sent = true;
        } else {
            $fld_sent = false;
        }
        if (isset($move_to_sent) && $move_to_sent != 0 || !isset($move_to_sent)) {
            $lcl_allow_sent = true;
        } else {
            $lcl_allow_sent = false;
        }
        if ($fld_sent && $svr_allow_sent && !$lcl_allow_sent || $fld_sent && $lcl_allow_sent) {
            if ($action == 'reply' || $action == 'reply_all') {
                $save_reply_with_orig = getPref($data_dir, $username, 'save_reply_with_orig');
                if ($save_reply_with_orig) {
                    $sent_folder = $mailbox;
                }
            }
            require_once SM_PATH . 'class/deliver/Deliver_IMAP.class.php';
            $imap_deliver = new Deliver_IMAP();
            $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id, $imap_stream, $sent_folder);
            unset($imap_deliver);
        }
        // final cleanup
        //
        $composeMessage->purgeAttachments();
        sqimap_logout($imap_stream);
    }
    return $success;
}
示例#9
0
/**
 * Recursively walk the tree of mailboxes in the given folder and delete all folders and messages
 *
 * @param int index the place in the tree to start, usually 0
 * @param stream imap_stream the IMAP connection to send commands to
 * @param array tree the tree to walk
 * @param mailbox the name of the root folder to empty
 * @return void
 */
function walkTreeInPreOrderEmptyFolder($index, $imap_stream, $tree, $mailbox)
{
    if ($tree[$index]['doIHaveChildren']) {
        for ($j = 0; $j < count($tree[$index]['subNodes']); $j++) {
            walkTreeInPreOrderEmptyTrash($tree[$index]['subNodes'][$j], $imap_stream, $tree);
        }
        if ($tree[$index]['value'] != $mailbox) {
            sqimap_mailbox_delete($imap_stream, $tree[$index]['value']);
        } else {
            $mbx_response = sqimap_mailbox_select($imap_stream, $mailbox);
            if ($mbx_response['EXISTS'] > 0) {
                sqimap_toggle_flag($imap_stream, '1:*', '\\Deleted', true, true);
                // CLOSE === EXPUNGE and UNSELECT
                sqimap_run_command($imap_stream, 'CLOSE', false, $response, $message);
            }
        }
    } else {
        if ($tree[$index]['value'] != $mailbox) {
            sqimap_mailbox_delete($imap_stream, $tree[$index]['value']);
        } else {
            $mbx_response = sqimap_mailbox_select($imap_stream, $mailbox);
            if ($mbx_response['EXISTS'] > 0) {
                sqimap_toggle_flag($imap_stream, '1:*', '\\Deleted', true, true);
                // CLOSE === EXPUNGE and UNSELECT
                sqimap_run_command($imap_stream, 'CLOSE', false, $response, $message);
            }
        }
    }
}
示例#10
0
        $read = sqimap_run_command($imapConnection, "FETCH {$passed_id} BODY[1.HEADER]", true, $response, $msg, TRUE);
        $rfc822_header = new Rfc822Header();
        $rfc822_header->parseHeader($read);
        $message->rfc822_header = $rfc822_header;
    } else {
        $passed_ent_id = 0;
    }
}
$header = $message->header;
// gmail does not mark messages as read when retrieving the message body
// even though RFC 3501, section 6.4.5 (FETCH Command) says:
// "The \Seen flag is implicitly set; if this causes the flags to change,
// they SHOULD be included as part of the FETCH responses."
//
if ($imap_server_type == 'gmail') {
    sqimap_toggle_flag($imapConnection, $passed_id, '\\Seen', true, true);
}
/****************************************/
/* Block for handling incoming url vars */
/****************************************/
if (isset($sendreceipt)) {
    if (!$message->is_mdnsent) {
        $supportMDN = ServerMDNSupport($aMailbox["PERMANENTFLAGS"]);
        if (SendMDN($mailbox, $passed_id, $message, $imapConnection) > 0 && $supportMDN) {
            ToggleMDNflag(true, $imapConnection, $mailbox, $passed_id);
            $message->is_mdnsent = true;
            $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'] = $message;
        }
    }
}
/***********************************************/