예제 #1
0
function newMail($mailbox = '', $passed_id = '', $passed_ent_id = '', $action = '', $session = '')
{
    global $editor_size, $default_use_priority, $body, $idents, $use_signature, $data_dir, $username, $key, $imapServerAddress, $imapPort, $imap_stream_options, $composeMessage, $body_quote, $request_mdn, $request_dr, $mdn_user_support, $languages, $squirrelmail_language, $default_charset, $do_not_reply_to_self;
    /*
     * Set $default_charset to correspond with the user's selection
     * of language interface. $default_charset global is not correct,
     * if message is composed in new window.
     */
    set_my_charset();
    $send_to = $send_to_cc = $send_to_bcc = $subject = $identity = '';
    $mailprio = 3;
    if ($passed_id) {
        $imapConnection = sqimap_login($username, false, $imapServerAddress, $imapPort, 0, $imap_stream_options);
        sqimap_mailbox_select($imapConnection, $mailbox);
        $message = sqimap_get_message($imapConnection, $passed_id, $mailbox);
        $body = '';
        if ($passed_ent_id) {
            /* redefine the messsage in case of message/rfc822 */
            $message = $message->getEntity($passed_ent_id);
            /* message is an entity which contains the envelope and type0=message
             * and type1=rfc822. The actual entities are childs from
             * $message->entities[0]. That's where the encoding and is located
             */
            $entities = $message->entities[0]->findDisplayEntity(array(), $alt_order = array('text/plain'));
            if (!count($entities)) {
                $entities = $message->entities[0]->findDisplayEntity(array(), $alt_order = array('text/plain', 'text/html'));
            }
            $orig_header = $message->rfc822_header;
            /* here is the envelope located */
            /* redefine the message for picking up the attachments */
            $message = $message->entities[0];
        } else {
            $entities = $message->findDisplayEntity(array(), $alt_order = array('text/plain'));
            if (!count($entities)) {
                $entities = $message->findDisplayEntity(array(), $alt_order = array('text/plain', 'text/html'));
            }
            $orig_header = $message->rfc822_header;
        }
        $type0 = $message->type0;
        $type1 = $message->type1;
        foreach ($entities as $ent) {
            $msg = $message->getEntity($ent);
            $type0 = $msg->type0;
            $type1 = $msg->type1;
            $unencoded_bodypart = mime_fetch_body($imapConnection, $passed_id, $ent);
            $body_part_entity = $message->getEntity($ent);
            $bodypart = decodeBody($unencoded_bodypart, $body_part_entity->header->encoding);
            if ($type1 == 'html') {
                $bodypart = str_replace("\n", ' ', $bodypart);
                $bodypart = preg_replace(array('/<\\/?p>/i', '/<div><\\/div>/i', '/<br\\s*(\\/)*>/i', '/<\\/?div>/i'), "\n", $bodypart);
                $bodypart = str_replace(array('&nbsp;', '&gt;', '&lt;'), array(' ', '>', '<'), $bodypart);
                $bodypart = strip_tags($bodypart);
            }
            if (isset($languages[$squirrelmail_language]['XTRA_CODE']) && function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_decode')) {
                if (mb_detect_encoding($bodypart) != 'ASCII') {
                    $bodypart = call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_decode', $bodypart);
                }
            }
            // charset encoding in compose form stuff
            if (isset($body_part_entity->header->parameters['charset'])) {
                $actual = $body_part_entity->header->parameters['charset'];
            } else {
                $actual = 'us-ascii';
            }
            if ($actual && is_conversion_safe($actual) && $actual != $default_charset) {
                $bodypart = charset_convert($actual, $bodypart, $default_charset, false);
            }
            // end of charset encoding in compose
            $body .= $bodypart;
        }
        if ($default_use_priority) {
            $mailprio = substr($orig_header->priority, 0, 1);
            if (!$mailprio) {
                $mailprio = 3;
            }
        } else {
            $mailprio = '';
        }
        $from_o = $orig_header->from;
        if (is_array($from_o)) {
            if (isset($from_o[0])) {
                $from_o = $from_o[0];
            }
        }
        if (is_object($from_o)) {
            $orig_from = $from_o->getAddress();
        } else {
            $orig_from = '';
        }
        $identities = array();
        if (count($idents) > 1) {
            foreach ($idents as $nr => $data) {
                $enc_from_name = '"' . $data['full_name'] . '" <' . $data['email_address'] . '>';
                $identities[] = $enc_from_name;
            }
            $identity_match = $orig_header->findAddress($identities);
            if ($identity_match !== FALSE) {
                $identity = $identity_match;
            }
        }
        switch ($action) {
            case 'draft':
                $use_signature = FALSE;
                $composeMessage->rfc822_header = $orig_header;
                $send_to = decodeHeader($orig_header->getAddr_s('to'), false, false, true);
                $send_to_cc = decodeHeader($orig_header->getAddr_s('cc'), false, false, true);
                $send_to_bcc = decodeHeader($orig_header->getAddr_s('bcc'), false, false, true);
                $send_from = $orig_header->getAddr_s('from');
                $send_from_parts = new AddressStructure();
                $send_from_parts = $orig_header->parseAddress($send_from);
                $send_from_add = $send_from_parts->mailbox . '@' . $send_from_parts->host;
                $identity = find_identity(array($send_from_add));
                $subject = decodeHeader($orig_header->subject, false, false, true);
                // Remember the receipt settings
                $request_mdn = $mdn_user_support && !empty($orig_header->dnt) ? '1' : '0';
                $request_dr = $mdn_user_support && !empty($orig_header->drnt) ? '1' : '0';
                /* remember the references and in-reply-to headers in case of an reply */
                //FIXME: it would be better to fiddle with headers inside of the message object or possibly when delivering the message to its destination (drafts folder?); is this possible?
                $composeMessage->rfc822_header->more_headers['References'] = $orig_header->references;
                $composeMessage->rfc822_header->more_headers['In-Reply-To'] = $orig_header->in_reply_to;
                // rewrap the body to clean up quotations and line lengths
                sqBodyWrap($body, $editor_size);
                $composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
                break;
            case 'edit_as_new':
                $send_to = decodeHeader($orig_header->getAddr_s('to'), false, false, true);
                $send_to_cc = decodeHeader($orig_header->getAddr_s('cc'), false, false, true);
                $send_to_bcc = decodeHeader($orig_header->getAddr_s('bcc'), false, false, true);
                $subject = decodeHeader($orig_header->subject, false, false, true);
                $mailprio = $orig_header->priority;
                $orig_from = '';
                $composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
                // rewrap the body to clean up quotations and line lengths
                sqBodyWrap($body, $editor_size);
                break;
            case 'forward':
                $send_to = '';
                $subject = getforwardSubject(decodeHeader($orig_header->subject, false, false, true));
                $body = getforwardHeader($orig_header) . $body;
                // the logic for calling sqUnWordWrap here would be to allow the browser to wrap the lines
                // forwarded message text should be as undisturbed as possible, so commenting out this call
                // sqUnWordWrap($body);
                $composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
                //add a blank line after the forward headers
                $body = "\n" . $body;
                break;
            case 'forward_as_attachment':
                $subject = getforwardSubject(decodeHeader($orig_header->subject, false, false, true));
                $composeMessage = getMessage_RFC822_Attachment($message, $composeMessage, $passed_id, $passed_ent_id, $imapConnection);
                $subject = decodeHeader($orig_header->subject, false, false, true);
                $subject = str_replace('"', "'", $subject);
                $subject = trim($subject);
                if (substr(strtolower($subject), 0, 4) != 'fwd:') {
                    $subject = 'Fwd: ' . $subject;
                }
                $body = '';
                break;
            case 'reply_all':
                if (isset($orig_header->mail_followup_to) && $orig_header->mail_followup_to) {
                    $send_to = $orig_header->getAddr_s('mail_followup_to');
                } else {
                    $send_to_cc = replyAllString($orig_header);
                    $send_to_cc = decodeHeader($send_to_cc, false, false, true);
                    $send_to_cc = str_replace('""', '"', $send_to_cc);
                }
            case 'reply':
                // skip this if send_to was already set right above here
                if (!$send_to) {
                    $send_to = $orig_header->reply_to;
                    if (is_array($send_to) && count($send_to)) {
                        $send_to = $orig_header->getAddr_s('reply_to', ',', FALSE, TRUE);
                    } else {
                        if (is_object($send_to)) {
                            /* unneccesarry, just for failsafe purpose */
                            $send_to = $orig_header->getAddr_s('reply_to', ',', FALSE, TRUE);
                        } else {
                            $send_to = $orig_header->getAddr_s('from', ',', FALSE, TRUE);
                        }
                    }
                }
                $send_to = decodeHeader($send_to, false, false, true);
                $send_to = str_replace('""', '"', $send_to);
                // If user doesn't want replies to her own messages
                // going back to herself (instead send again to the
                // original recipient of the message being replied to),
                // then iterate through identities, checking if the TO
                // field is one of them (if the reply is to ourselves)
                //
                // Note we don't bother if the original message doesn't
                // have anything in the TO field itself (because that's
                // what we use if we change the recipient to be that of
                // the previous message)
                //
                if ($do_not_reply_to_self && !empty($orig_header->to)) {
                    $orig_to = '';
                    foreach ($idents as $id) {
                        if (!empty($id['email_address']) && strpos($send_to, $id['email_address']) !== FALSE) {
                            // if this is a reply-all, the original recipient
                            // is already in the CC field, so we can just blank
                            // the recipient (TO field) (as long as the CC field
                            // isn't empty that is)... but then move the CC into
                            // the TO, so TO isn't empty
                            //
                            if ($action == 'reply_all' && !empty($send_to_cc)) {
                                $orig_to = $send_to_cc;
                                $send_to_cc = '';
                                break;
                            }
                            $orig_to = $orig_header->to;
                            if (is_array($orig_to) && count($orig_to)) {
                                $orig_to = $orig_header->getAddr_s('to', ',', FALSE, TRUE);
                            } else {
                                if (is_object($orig_to)) {
                                    /* unneccesarry, just for failsafe purpose */
                                    $orig_to = $orig_header->getAddr_s('to', ',', FALSE, TRUE);
                                } else {
                                    $orig_to = '';
                                }
                            }
                            $orig_to = decodeHeader($orig_to, false, false, true);
                            $orig_to = str_replace('""', '"', $orig_to);
                            break;
                        }
                    }
                    // if the reply was addressed back to ourselves,
                    // we will send it to the TO of the previous message
                    //
                    if (!empty($orig_to)) {
                        $send_to = $orig_to;
                        // in this case, we also want to reset the FROM
                        // identity as well (it should match the original
                        // *FROM* header instead of TO or CC)
                        //
                        if (count($idents) > 1) {
                            $identity = '';
                            foreach ($idents as $i => $id) {
                                if (!empty($id['email_address']) && strpos($orig_from, $id['email_address']) !== FALSE) {
                                    $identity = $i;
                                    break;
                                }
                            }
                        }
                    }
                }
                $subject = decodeHeader($orig_header->subject, false, false, true);
                $subject = str_replace('"', "'", $subject);
                $subject = trim($subject);
                if (substr(strtolower($subject), 0, 3) != 're:') {
                    $subject = 'Re: ' . $subject;
                }
                /* this corrects some wrapping/quoting problems on replies */
                $rewrap_body = explode("\n", $body);
                $from = is_array($orig_header->from) && !empty($orig_header->from) ? $orig_header->from[0] : $orig_header->from;
                $body = '';
                $strip_sigs = getPref($data_dir, $username, 'strip_sigs');
                foreach ($rewrap_body as $line) {
                    if ($strip_sigs && rtrim($line, "\r\n") == '-- ') {
                        break;
                    }
                    if (preg_match("/^(>+)/", $line, $matches)) {
                        $gt = $matches[1];
                        $body .= $body_quote . str_replace("\n", "\n{$body_quote}{$gt} ", rtrim($line)) . "\n";
                    } else {
                        $body .= $body_quote . (!empty($body_quote) ? ' ' : '') . str_replace("\n", "\n{$body_quote}" . (!empty($body_quote) ? ' ' : ''), rtrim($line)) . "\n";
                    }
                }
                //rewrap the body to clean up quotations and line lengths
                $body = sqBodyWrap($body, $editor_size);
                $body = getReplyCitation($from, $orig_header->date) . $body;
                $composeMessage->reply_rfc822_header = $orig_header;
                break;
            default:
                break;
        }
        //FIXME: we used to register $compose_messages in the session here, but not any more - so do we still need the session_write_close() and sqimap_logout() here?  We probably need the IMAP logout, but what about the session closure?
        session_write_close();
        sqimap_logout($imapConnection);
    }
    $ret = array('send_to' => $send_to, 'send_to_cc' => $send_to_cc, 'send_to_bcc' => $send_to_bcc, 'subject' => $subject, 'mailprio' => $mailprio, 'body' => $body, 'identity' => $identity);
    return $ret;
}
예제 #2
0
function SendMDN($mailbox, $passed_id, $message, $imapConnection)
{
    global $squirrelmail_language, $default_charset, $default_move_to_sent, $languages, $useSendmail, $domain, $sent_folder, $username, $data_dir;
    sqgetGlobalVar('SERVER_NAME', $SERVER_NAME, SQ_SERVER);
    $header = $message->rfc822_header;
    $rfc822_header = new Rfc822Header();
    $content_type = new ContentType('multipart/report');
    $content_type->properties['report-type'] = 'disposition-notification';
    set_my_charset();
    if ($default_charset) {
        $content_type->properties['charset'] = $default_charset;
    }
    $rfc822_header->content_type = $content_type;
    $rfc822_header->to[] = $header->dnt;
    $rfc822_header->subject = _("Read:") . ' ' . decodeHeader($header->subject, true, false);
    $idents = get_identities();
    $needles = array();
    if ($header->to) {
        foreach ($header->to as $message_to) {
            $needles[] = $message_to->mailbox . '@' . $message_to->host;
        }
    }
    $identity = find_identity($needles);
    $from_addr = build_from_header($identity);
    $reply_to = isset($idents[$identity]['reply_to']) ? $idents[$identity]['reply_to'] : '';
    // FIXME: this must actually be the envelope address of the orginal message,
    // but do we have that information? For now the first identity is our best guess.
    $final_recipient = $idents[0]['email_address'];
    $rfc822_header->from = $rfc822_header->parseAddress($from_addr, true);
    if ($reply_to) {
        $rfc822_header->reply_to = $rfc822_header->parseAddress($reply_to, true);
    }
    // part 1 (RFC2298)
    $senton = getLongDateString($header->date, $header->date_unparsed);
    $to_array = $header->to;
    $to = '';
    foreach ($to_array as $line) {
        $to .= ' ' . $line->getAddress();
    }
    $now = getLongDateString(time());
    set_my_charset();
    $body = _("Your message") . "\r\n\r\n" . "\t" . _("To") . ': ' . decodeHeader($to, false, false) . "\r\n" . "\t" . _("Subject") . ': ' . decodeHeader($header->subject, false, false) . "\r\n" . "\t" . _("Sent") . ': ' . $senton . "\r\n" . "\r\n" . sprintf(_("Was displayed on %s"), $now);
    $special_encoding = '';
    if (isset($languages[$squirrelmail_language]['XTRA_CODE']) && function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_encode')) {
        $body = call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_encode', $body);
        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';
            }
        }
    } elseif (sq_is8bit($body)) {
        $special_encoding = '8bit';
    }
    $part1 = new Message();
    $part1->setBody($body);
    $mime_header = new MessageHeader();
    $mime_header->type0 = 'text';
    $mime_header->type1 = 'plain';
    if ($special_encoding) {
        $mime_header->encoding = $special_encoding;
    } else {
        $mime_header->encoding = '7bit';
    }
    if ($default_charset) {
        $mime_header->parameters['charset'] = $default_charset;
    }
    $part1->mime_header = $mime_header;
    // part2  (RFC2298)
    $original_recipient = $to;
    $original_message_id = $header->message_id;
    $report = "Reporting-UA : {$SERVER_NAME} ; SquirrelMail (version " . SM_VERSION . ") \r\n";
    if ($original_recipient != '') {
        $report .= "Original-Recipient : {$original_recipient}\r\n";
    }
    $report .= "Final-Recipient: rfc822; {$final_recipient}\r\n" . "Original-Message-ID : {$original_message_id}\r\n" . "Disposition: manual-action/MDN-sent-manually; displayed\r\n";
    $part2 = new Message();
    $part2->setBody($report);
    $mime_header = new MessageHeader();
    $mime_header->type0 = 'message';
    $mime_header->type1 = 'disposition-notification';
    $mime_header->encoding = '7bit';
    $part2->mime_header = $mime_header;
    $composeMessage = new Message();
    $composeMessage->rfc822_header = $rfc822_header;
    $composeMessage->addEntity($part1);
    $composeMessage->addEntity($part2);
    if ($useSendmail) {
        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);
    } else {
        require_once SM_PATH . 'class/deliver/Deliver_SMTP.class.php';
        $deliver = new Deliver_SMTP();
        global $smtpServerAddress, $smtpPort, $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);
    }
    $success = false;
    if ($stream) {
        $deliver->mail($composeMessage, $stream);
        $success = $deliver->finalizeStream($stream);
    }
    if (!$success) {
        $msg = _("Message not sent.") . "\n" . $deliver->dlv_msg;
        if (!empty($deliver->dlv_server_msg)) {
            $msg .= "\n" . _("Server replied:") . ' ' . $deliver->dlv_ret_nr . ' ' . nl2br(sm_encode_html_special_chars($deliver->dlv_server_msg));
        }
        plain_error_message($msg);
    } else {
        unset($deliver);
        // 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($imapConnection, $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) {
            $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, $imapConnection, 0, 0, $imapConnection, $sent_folder);
            unset($imap_deliver);
        }
    }
    return $success;
}