1<?php 2 3/** 4 +-----------------------------------------------------------------------+ 5 | This file is part of the Roundcube Webmail client | 6 | | 7 | Copyright (C) The Roundcube Dev Team | 8 | | 9 | Licensed under the GNU General Public License version 3 or | 10 | any later version with exceptions for skins & plugins. | 11 | See the README file for a full license statement. | 12 | | 13 | PURPOSE: | 14 | Send a message disposition notification for a specific mail | 15 +-----------------------------------------------------------------------+ 16 | Author: Thomas Bruederli <roundcube@gmail.com> | 17 +-----------------------------------------------------------------------+ 18*/ 19 20class rcmail_action_mail_sendmdn extends rcmail_action 21{ 22 protected static $mode = self::MODE_AJAX; 23 24 /** 25 * Request handler. 26 * 27 * @param array $args Arguments from the previous step(s) 28 */ 29 public function run($args = []) 30 { 31 $rcmail = rcmail::get_instance(); 32 33 if ($uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST)) { 34 $sent = self::send_mdn($uid, $smtp_error); 35 } 36 37 // show either confirm or error message 38 if (!empty($sent)) { 39 $rcmail->output->set_env('mdn_request', false); 40 $rcmail->output->show_message('receiptsent', 'confirmation'); 41 } 42 else if (!empty($smtp_error) && is_string($smtp_error)) { 43 $rcmail->output->show_message($smtp_error, 'error'); 44 } 45 else if (!empty($smtp_error) && !empty($smtp_error['label'])) { 46 $rcmail->output->show_message($smtp_error['label'], 'error', $smtp_error['vars']); 47 } 48 else { 49 $rcmail->output->show_message('errorsendingreceipt', 'error'); 50 } 51 52 // Redirect to 'addcontact' action to save the sender address 53 if (!empty($_POST['_save'])) { 54 if ($_POST['_save'] == 5) { 55 $_POST['_source'] = rcube_addressbook::TYPE_TRUSTED_SENDER; 56 } 57 58 $rcmail->action = 'addcontact'; 59 return; 60 } 61 62 $rcmail->output->send(); 63 } 64 65 /** 66 * Send the MDN response 67 * 68 * @param mixed $message Original message object (rcube_message) or UID 69 * @param array|string $smtp_error SMTP error array or (deprecated) string 70 * 71 * @return boolean Send status 72 */ 73 public static function send_mdn($message, &$smtp_error) 74 { 75 $rcmail = rcmail::get_instance(); 76 77 if (!is_object($message) || !is_a($message, 'rcube_message')) { 78 $message = new rcube_message($message); 79 } 80 81 if ($message->headers->mdn_to && empty($message->headers->flags['MDNSENT']) && 82 ($rcmail->storage->check_permflag('MDNSENT') || $rcmail->storage->check_permflag('*')) 83 ) { 84 $charset = $message->headers->charset; 85 $identity = rcmail_sendmail::identity_select($message); 86 $sender = format_email_recipient($identity['email'], $identity['name']); 87 $recipient = array_first(rcube_mime::decode_address_list($message->headers->mdn_to, 1, true, $charset)); 88 $mailto = $recipient['mailto']; 89 90 $compose = new Mail_mime("\r\n"); 91 92 $compose->setParam('text_encoding', 'quoted-printable'); 93 $compose->setParam('html_encoding', 'quoted-printable'); 94 $compose->setParam('head_encoding', 'quoted-printable'); 95 $compose->setParam('head_charset', RCUBE_CHARSET); 96 $compose->setParam('html_charset', RCUBE_CHARSET); 97 $compose->setParam('text_charset', RCUBE_CHARSET); 98 99 // compose headers array 100 $headers = [ 101 'Date' => $rcmail->user_date(), 102 'From' => $sender, 103 'To' => $message->headers->mdn_to, 104 'Subject' => $rcmail->gettext('receiptread') . ': ' . $message->subject, 105 'Message-ID' => $rcmail->gen_message_id($identity['email']), 106 'X-Sender' => $identity['email'], 107 'References' => trim($message->headers->references . ' ' . $message->headers->messageID), 108 'In-Reply-To' => $message->headers->messageID, 109 ]; 110 111 $report = "Final-Recipient: rfc822; {$identity['email']}\r\n" 112 . "Original-Message-ID: {$message->headers->messageID}\r\n" 113 . "Disposition: manual-action/MDN-sent-manually; displayed\r\n"; 114 115 if ($message->headers->to) { 116 $report .= "Original-Recipient: {$message->headers->to}\r\n"; 117 } 118 119 if ($agent = $rcmail->config->get('useragent')) { 120 $headers['User-Agent'] = $agent; 121 $report .= "Reporting-UA: $agent\r\n"; 122 } 123 124 $to = rcube_mime::decode_mime_string($message->headers->to, $charset); 125 $date = $rcmail->format_date($message->headers->date, $rcmail->config->get('date_long')); 126 $body = $rcmail->gettext("yourmessage") . "\r\n\r\n" . 127 "\t" . $rcmail->gettext("to") . ": {$to}\r\n" . 128 "\t" . $rcmail->gettext("subject") . ": {$message->subject}\r\n" . 129 "\t" . $rcmail->gettext("date") . ": {$date}\r\n" . 130 "\r\n" . $rcmail->gettext("receiptnote"); 131 132 $compose->headers(array_filter($headers)); 133 $compose->setContentType('multipart/report', ['report-type'=> 'disposition-notification']); 134 $compose->setTXTBody(rcube_mime::wordwrap($body, 75, "\r\n")); 135 $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline'); 136 137 // SMTP options 138 $options = ['mdn_use_from' => (bool) $rcmail->config->get('mdn_use_from')]; 139 140 $sent = $rcmail->deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file, $options, true); 141 142 if ($sent) { 143 $rcmail->storage->set_flag($message->uid, 'MDNSENT'); 144 return true; 145 } 146 } 147 148 return false; 149 } 150} 151