- Support SMTP Delivery Status Notifications - RFC3461 (#1486142)
| | |
| | | - Add unique index on users.username+users.mail_host |
| | | - Make htmleditor option more consistent and add option to use HTML on reply to HTML message (#1485840) |
| | | - Use empty envelope sender address for message disposition notifications (RFC2298.3) |
| | | - Support SMTP Delivery Status Notifications - RFC3461 (#1486142) |
| | | |
| | | RELEASE 0.4.2 |
| | | ------------- |
| | |
| | | // if in your system 0 quota means no limit set this option to true |
| | | $rcmail_config['quota_zero_as_unlimited'] = false; |
| | | |
| | | // Behavior if a received message requests a message delivery notification (read receipt) |
| | | // 0 = ask the user, 1 = send automatically, 2 = ignore (never send or ask) |
| | | // 3 = send automatically if sender is in addressbook, otherwise ask the user |
| | | // 4 = send automatically if sender is in addressbook, otherwise ignore |
| | | $rcmail_config['mdn_requests'] = 0; |
| | | |
| | | // Make use of the built-in spell checker. It is based on GoogieSpell. |
| | | // Since Google only accepts connections over https your PHP installatation |
| | | // requires to be compiled with Open SSL support |
| | |
| | | // when user is over quota and Trash is included in the quota. |
| | | $rcmail_config['delete_always'] = false; |
| | | |
| | | // end of config file |
| | | // Behavior if a received message requests a message delivery notification (read receipt) |
| | | // 0 = ask the user, 1 = send automatically, 2 = ignore (never send or ask) |
| | | // 3 = send automatically if sender is in addressbook, otherwise ask the user |
| | | // 4 = send automatically if sender is in addressbook, otherwise ignore |
| | | $rcmail_config['mdn_requests'] = 0; |
| | | |
| | | // Return receipt checkbox default state |
| | | $rcmail_config['mdn_default'] = 0; |
| | | |
| | | // Delivery Status Notification checkbox default state |
| | | $rcmail_config['dsn_default'] = 0; |
| | | |
| | | // end of config file |
| | |
| | | if ($part_orig_mimetype == 'message/rfc822' && !empty($mail_part->filename)) |
| | | $this->attachments[] = $mail_part; |
| | | } |
| | | // part text/[plain|html] OR message/delivery-status |
| | | // part text/[plain|html] or delivery status |
| | | else if ((($part_mimetype == 'text/plain' || $part_mimetype == 'text/html') && $mail_part->disposition != 'attachment') || |
| | | $part_mimetype == 'message/delivery-status' || $part_mimetype == 'message/disposition-notification' |
| | | in_array($part_mimetype, array('message/delivery-status', 'text/rfc822-headers', 'message/disposition-notification')) |
| | | ) { |
| | | // Allow plugins to handle also this part |
| | | $plugin = $this->app->plugins->exec_hook('message_part_structure', |
| | |
| | | * each RFC822 valid. This may contain recipients not |
| | | * specified in the headers, for Bcc:, resending |
| | | * messages, etc. |
| | | * |
| | | * @param mixed The message headers to send with the mail |
| | | * Either as an associative array or a finally |
| | | * formatted string |
| | | * |
| | | * @param mixed The full text of the message body, including any Mime parts |
| | | * or file handle |
| | | * @param array Delivery options (e.g. DSN request) |
| | | * |
| | | * @return bool Returns true on success, or false on error |
| | | */ |
| | | public function send_mail($from, $recipients, &$headers, &$body) |
| | | public function send_mail($from, $recipients, &$headers, &$body, $opts=null) |
| | | { |
| | | if (!is_object($this->conn)) |
| | | return false; |
| | |
| | | else |
| | | { |
| | | $this->reset(); |
| | | $this->response[] .= "Invalid message headers"; |
| | | $this->response[] = "Invalid message headers"; |
| | | return false; |
| | | } |
| | | |
| | |
| | | if (!isset($from)) |
| | | { |
| | | $this->reset(); |
| | | $this->response[] .= "No From address has been provided"; |
| | | $this->response[] = "No From address has been provided"; |
| | | return false; |
| | | } |
| | | |
| | | // RFC3461: Delivery Status Notification |
| | | if ($opts['dsn']) { |
| | | $exts = $this->conn->getServiceExtensions(); |
| | | |
| | | if (!isset($exts['DSN'])) { |
| | | $this->error = array('label' => 'smtpdsnerror'); |
| | | $this->response[] = "DSN not supported"; |
| | | return false; |
| | | } |
| | | |
| | | $from_params = 'RET=HDRS'; |
| | | $recipient_params = 'NOTIFY=SUCCESS,FAILURE'; |
| | | } |
| | | |
| | | // RFC2298.3: remove envelope sender address |
| | |
| | | } |
| | | |
| | | // set From: address |
| | | if (PEAR::isError($this->conn->mailFrom($from))) |
| | | if (PEAR::isError($this->conn->mailFrom($from, $from_params))) |
| | | { |
| | | $err = $this->conn->getResponse(); |
| | | $this->error = array('label' => 'smtpfromerror', 'vars' => array( |
| | | 'from' => $from, 'code' => $this->conn->_code, 'msg' => $err[1])); |
| | | $this->response[] .= "Failed to set sender '$from'"; |
| | | $this->response[] = "Failed to set sender '$from'"; |
| | | $this->reset(); |
| | | return false; |
| | | } |
| | |
| | | // set mail recipients |
| | | foreach ($recipients as $recipient) |
| | | { |
| | | if (PEAR::isError($this->conn->rcptTo($recipient))) { |
| | | if (PEAR::isError($this->conn->rcptTo($recipient, $recipient_params))) { |
| | | $err = $this->conn->getResponse(); |
| | | $this->error = array('label' => 'smtptoerror', 'vars' => array( |
| | | 'to' => $recipient, 'code' => $this->conn->_code, 'msg' => $err[1])); |
| | | $this->response[] .= "Failed to add recipient '$recipient'"; |
| | | $this->response[] = "Failed to add recipient '$recipient'"; |
| | | $this->reset(); |
| | | return false; |
| | | } |
| | |
| | | $msg = $result->getMessage(); |
| | | |
| | | $this->error = array('label' => 'smtperror', 'vars' => array('msg' => $msg)); |
| | | $this->response[] .= "Failed to send data"; |
| | | $this->response[] = "Failed to send data"; |
| | | $this->reset(); |
| | | return false; |
| | | } |
| | |
| | | $labels['charset'] = 'Charset'; |
| | | $labels['editortype'] = 'Editor type'; |
| | | $labels['returnreceipt'] = 'Return receipt'; |
| | | $labels['dsn'] = 'Delivery status notification'; |
| | | |
| | | $labels['editidents'] = 'Edit identities'; |
| | | $labels['checkspelling'] = 'Check spelling'; |
| | |
| | | $labels['previewpanemarkread'] = 'Mark previewed messages as read'; |
| | | $labels['afternseconds'] = 'after $n seconds'; |
| | | $labels['reqmdn'] = 'Always request a return receipt'; |
| | | $labels['reqdsn'] = 'Always request a delivery status notification'; |
| | | |
| | | $labels['folder'] = 'Folder'; |
| | | $labels['folders'] = 'Folders'; |
| | |
| | | $messages['smtpfromerror'] = 'SMTP Error ($code): Failed to set sender "$from" ($msg)'; |
| | | $messages['smtptoerror'] = 'SMTP Error ($code): Failed to add recipient "$to" ($msg)'; |
| | | $messages['smtprecipientserror'] = 'SMTP Error: Unable to parse recipients list'; |
| | | $messages['smtpdsnerror'] = 'SMTP Error: No support for Delivery Status Notifications'; |
| | | $messages['smtperror'] = 'SMTP Error: $msg'; |
| | | $messages['emailformaterror'] = 'Invalid e-mail address: $email'; |
| | | $messages['toomanyrecipients'] = 'Too many recipients. Reduce the number of recipients to $max.'; |
| | |
| | | $labels['editidents'] = 'Edytuj tożsamości'; |
| | | $labels['addmailreplyto'] = 'Dodaj Mail-Reply-To'; |
| | | $labels['addmailfollowupto'] = 'Dodaj Mail-Followup-To'; |
| | | $labels['dsn'] = 'Status dostarczenia (DSN)'; |
| | | $labels['reqdsn'] = 'Zawsze żądaj statusu dostarczenia (DSN)'; |
| | | |
| | | ?> |
| | |
| | | $messages['smtpfromerror'] = 'Błąd SMTP ($code): Nie można ustawić nadawcy "$from" ($msg)'; |
| | | $messages['smtptoerror'] = 'Błąd SMTP ($code): Nie można dodać odbiorcy "$to" ($msg)'; |
| | | $messages['smtprecipientserror'] = 'Błąd SMTP: Parsowanie listy odbiorców nie powiodło się'; |
| | | $messages['smtpdsnerror'] = 'Błąd SMTP: Statusy dostarczenia (DSN) nie są obsługiwane przez serwer'; |
| | | $messages['smtperror'] = 'Błąd SMTP: $msg'; |
| | | $messages['emailformaterror'] = 'Błędny adres e-mail: $email'; |
| | | $messages['toomanyrecipients'] = 'Zbyt wielu odbiorców. Zmniejsz ich liczbę do $max.'; |
| | |
| | | } |
| | | |
| | | |
| | | function rcmail_dsn_checkbox($attrib) |
| | | { |
| | | global $RCMAIL; |
| | | |
| | | list($form_start, $form_end) = get_form_tags($attrib); |
| | | unset($attrib['form']); |
| | | |
| | | if (!isset($attrib['id'])) |
| | | $attrib['id'] = 'dsn'; |
| | | |
| | | $attrib['name'] = '_dsn'; |
| | | $attrib['value'] = '1'; |
| | | $checkbox = new html_checkbox($attrib); |
| | | |
| | | $out = $form_start ? "$form_start\n" : ''; |
| | | $out .= $checkbox->show($RCMAIL->config->get('dsn_default')); |
| | | $out .= $form_end ? "\n$form_end" : ''; |
| | | |
| | | return $out; |
| | | } |
| | | |
| | | |
| | | function rcmail_editor_selector($attrib) |
| | | { |
| | | global $CONFIG, $MESSAGE, $compose_mode; |
| | |
| | | 'priorityselector' => 'rcmail_priority_selector', |
| | | 'editorselector' => 'rcmail_editor_selector', |
| | | 'receiptcheckbox' => 'rcmail_receipt_checkbox', |
| | | 'dsncheckbox' => 'rcmail_dsn_checkbox', |
| | | 'storetarget' => 'rcmail_store_target_selection', |
| | | )); |
| | | |
| | |
| | | * @param array $mailto Array of recipient address strings |
| | | * @param array $smtp_error SMTP error array (reference) |
| | | * @param string $body_file Location of file with saved message body (reference) |
| | | * @param array $smtp_opts SMTP options (e.g. DSN request) |
| | | * |
| | | * @return boolean Send status. |
| | | */ |
| | | function rcmail_deliver_message(&$message, $from, $mailto, &$smtp_error, &$body_file) |
| | | function rcmail_deliver_message(&$message, $from, $mailto, &$smtp_error, &$body_file, $smtp_opts=null) |
| | | { |
| | | global $CONFIG, $RCMAIL; |
| | | |
| | |
| | | if (!is_object($RCMAIL->smtp)) |
| | | $RCMAIL->smtp_init(true); |
| | | |
| | | $sent = $RCMAIL->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body); |
| | | $sent = $RCMAIL->smtp->send_mail($from, $a_recipients, $smtp_headers, $msg_body, $smtp_opts); |
| | | $smtp_response = $RCMAIL->smtp->get_response(); |
| | | $smtp_error = $RCMAIL->smtp->get_error(); |
| | | |
| | |
| | | $OUTPUT->send('iframe'); |
| | | } |
| | | |
| | | $sent = rcmail_deliver_message($MAIL_MIME, $from, $mailto, $smtp_error, $mailbody_file); |
| | | // Handle Delivery Status Notification request |
| | | if (!empty($_POST['_dsn'])) { |
| | | $smtp_opts['dsn'] = true; |
| | | } |
| | | |
| | | $sent = rcmail_deliver_message($MAIL_MIME, $from, $mailto, |
| | | $smtp_error, $mailbody_file, $smtp_opts); |
| | | |
| | | // return to compose page if sending failed |
| | | if (!$sent) |
| | |
| | | ); |
| | | } |
| | | |
| | | if (!isset($no_override['dsn_default'])) { |
| | | $field_id = 'rcmfd_dsn_default'; |
| | | $input_dsn = new html_checkbox(array('name' => '_dsn_default', 'id' => $field_id, 'value' => 1)); |
| | | |
| | | $blocks['main']['options']['dsn_default'] = array( |
| | | 'title' => html::label($field_id, Q(rcube_label('reqdsn'))), |
| | | 'content' => $input_dsn->show($config['dsn_default']?1:0), |
| | | ); |
| | | } |
| | | |
| | | if (!isset($no_override['top_posting'])) { |
| | | $field_id = 'rcmfd_top_posting'; |
| | | $select_replymode = new html_select(array('name' => '_top_posting', 'id' => $field_id, 'onchange' => "\$('#rcmfd_sig_above').attr('disabled',this.selectedIndex==0)")); |
| | |
| | | 'mime_param_folding' => isset($_POST['_mime_param_folding']) ? intval($_POST['_mime_param_folding']) : 0, |
| | | 'force_7bit' => isset($_POST['_force_7bit']) ? TRUE : FALSE, |
| | | 'mdn_default' => isset($_POST['_mdn_default']) ? TRUE : FALSE, |
| | | 'dsn_default' => isset($_POST['_dsn_default']) ? TRUE : FALSE, |
| | | 'show_sig' => isset($_POST['_show_sig']) ? intval($_POST['_show_sig']) : 1, |
| | | 'top_posting' => !empty($_POST['_top_posting']), |
| | | 'strip_existing_sig' => isset($_POST['_strip_existing_sig']), |
| | |
| | | <td><label for="rcmcomposereceipt"><roundcube:label name="returnreceipt" />:</label></td> |
| | | <td><roundcube:object name="receiptCheckBox" form="form" id="rcmcomposereceipt" /></td> |
| | | </tr><tr> |
| | | <td><label for="rcmcomposedsn"><roundcube:label name="dsn" />:</label></td> |
| | | <td><roundcube:object name="dsnCheckBox" form="form" id="rcmcomposedsn" /></td> |
| | | </tr><tr> |
| | | <td><label for="rcmcomposepriority"><roundcube:label name="priority" />:</label></td> |
| | | <td><roundcube:object name="prioritySelector" form="form" id="rcmcomposepriority" /></td> |
| | | </tr><tr> |