nocc_webmail/webmail/classes/class_send.php
2022-01-03 15:03:38 +01:00

362 lines
11 KiB
PHP

<?php
/**
* Class for building and sending a mail
*
* Copyright 2001 Nicolas Chalanset <nicocha@free.fr>
* Copyright 2001 Olivier Cahagne <cahagn_o@epita.fr>
* Copyright 2008-2011 Tim Gerundt <tim@gerundt.de>
*
* This file is part of NOCC. NOCC is free software under the terms of the
* GNU General Public License. You should have received a copy of the license
* along with NOCC. If not, see <http://www.gnu.org/licenses/>.
*
* @package NOCC
* @license http://www.gnu.org/licenses/ GNU General Public License
* @version SVN: $Id: class_send.php 2871 2020-04-13 14:16:02Z oheil $
*/
require_once 'exception.php';
/**
* Building and sending a mail
*
* @package NOCC
* @todo Rename to NOCC_MimeMail?
*/
class mime_mail {
/**
* Parts
* @var array
*/
public $parts;
/**
* To addresses
* @var array
*/
public $to;
/**
* CC addresses
* @var array
*/
public $cc;
/**
* BCC addresses
* @var array
*/
public $bcc;
/**
* From address
* @var string
*/
public $from;
/**
* Headers
* @var string
*/
public $headers;
/**
* Subject
* @var string
*/
public $subject;
/**
* Body
* @var string
*/
public $body;
/**
* SMTP Server
* @var string
*/
public $smtp_server;
/**
* SMTP Port
* @var int
*/
public $smtp_port;
/**
* Charset
* @var string
*/
public $charset;
/**
* Linefeed
* @var string
*/
public $crlf;
/**
* Priority
* @var string
*/
public $priority;
/**
* Receipt
* @var bool
*/
public $receipt;
/**
* Initialize the mail object
*/
public function __construct() {
$this->parts = Array();
$this->to = Array();
$this->cc = Array();
$this->bcc = Array();
$this->from = null;
$this->headers = null;
$this->subject = null;
$this->body = null;
$this->smtp_server = 'localhost';
$this->smtp_port = 25;
$this->charset = 'UTF-8';
$this->crlf = null;
$this->priority = '3 (Normal)';
$this->receipt = false;
}
/**
* Add an attachment to the mail object
*
* @param string $message
* @param string $name
* @param string $ctype
* @param string $encoding
* @param string $charset
* @todo Rename to addAttachment()?
*/
public function add_attachment($message, $name, $ctype, $encoding, $charset) {
$this->parts[] = array (
'ctype' => $ctype,
'message' => $message,
'encoding' => $encoding,
'charset' => $charset,
'name' => $name
);
}
/**
* Build a message part
*
* @param array $part
* @return string
* @access private
*/
private function _buildMessage($part) {
$message = $part['message'];
$encoding = $part['encoding'];
$charset = $part['charset'];
switch($encoding) {
case 'base64':
$message = chunk_split(base64_encode($message));
break;
case 'quoted-printable':
$message = quoted_printable_encode($message);
break;
}
$val = 'Content-Type: ' . $part['ctype'] . ';';
$val .= ($part['charset'] ? $this->crlf . "\tcharset=\"" . $part['charset'] . '"' : '');
$val .= ($part['name'] ? $this->crlf . "\tname=\"" . $part['name'] . '"' : '');
$val .= $this->crlf . 'Content-Transfer-Encoding: ' . $encoding;
$val .= ($part['name'] ? $this->crlf . 'Content-Disposition: attachment;' . $this->crlf . "\tfilename=\"" . $part['name'] . '"' : '');
$val .= $this->crlf . $this->crlf . $message . $this->crlf;
return($val);
}
/**
* Build a multipart mail
*
* @return string
* @access private
*/
private function _buildMultipart() {
$boundary = 'NextPart'.md5(uniqid(rand(),true));
$multipart = 'Content-Type: multipart/mixed;' . $this->crlf . "\tboundary=\"$boundary\"" . $this->crlf . $this->crlf . 'This is a MIME encoded message.' . $this->crlf . $this->crlf . '--' . $boundary;
for($i = sizeof($this->parts) - 1; $i >= 0; $i--)
$multipart .= $this->crlf . $this->_buildMessage($this->parts[$i]) . '--'.$boundary;
return ($multipart .= '--' . $this->crlf);
}
/**
* Build a none multipart mail
*
* @return string
* @access private
*/
private function _buildNoneMultipart() {
if (sizeof($this->parts) == 1)
$part = $this->_buildMessage($this->parts[0]);
else
$part = '';
return ($part . $this->crlf);
}
/**
* Send the mail (last class-function to be called)
*
* @param $conf
* @return mixed
*/
public function send(&$conf) {
$mime = '';
if ($this->useSmtpServer()) { //if use SMTP server...
if ($this->to[0] != '')
$mime .= 'To: ' . join(', ', $this->to) . $this->crlf;
if (!empty($this->subject)) {
$mime .= 'Subject: ' . $this->subject . $this->crlf;
}
}
if (!empty($this->from))
$mime .= 'From: ' . $this->from . $this->crlf;
if (count($this->cc) > 0 && $this->cc[0] != '')
$mime .= 'Cc: ' . join(', ', $this->cc) . $this->crlf;
if (count($this->bcc) > 0 && $this->bcc[0] != '')
$mime .= 'Bcc: ' . join(', ', $this->bcc) . $this->crlf;
$mime .= 'Date: ' . date('r') . $this->crlf;
if (!empty($this->from))
$mime .= 'Reply-To: ' . $this->from . $this->crlf . 'Errors-To: '.$this->from . $this->crlf;
if ($this->receipt != false)
$mime .= 'Disposition-Notification-To: ' . $this->from . $this->crlf;
$mime .= 'X-Priority: ' . $this->priority . $this->crlf;
if (!empty($this->headers))
$mime .= $this->headers . $this->crlf;
// Strip lonely "\r\n.\r\n" in order to avoid STMP errors
$mime = str_replace("\r\n.\r\n", "\r\n..\r\n", $mime);
$mail_format = '';
if (NOCC_Session::getSendHtmlMail()) {
$mail_format = 'text/html';
}
else {
$mail_format = 'text/plain';
}
if (sizeof($this->parts) >= 1) {
$this->add_attachment($this->body, '', $mail_format, 'quoted-printable', $this->charset);
$mime .= 'MIME-Version: 1.0' . $this->crlf . $this->_buildMultipart();
}
else {
$this->add_attachment($this->body, '', $mail_format, '8bit', $this->charset);
$mime .= 'MIME-Version: 1.0' . $this->crlf . $this->_buildNoneMultipart();
}
// We enforce $conf->crlf option as mixed "\r\n" (coming from NOCC
// textarea while writing mail) and "\n" line break may confuse some
// MTA or mail() PHP function.
$mime = str_replace("\r\n", $conf->crlf, $mime);
// Whether or not to use SMTP or sendmail
// depends on the config file (conf.php)
if (!$this->useSmtpServer()) { //if use sendmail...
$rcpt_to = join(', ', $this->to);
$ev = @mail($rcpt_to, $this->subject, '', $mime, '-f' . $this->strip_comment($this->from));
$user_prefs = NOCC_Session::getUserPrefs();
if ($user_prefs->getUseSentFolder() && $user_prefs->getSentFolderName() != '') {
// Copy email to Sent folder
//TODO: Optimize try block!
try {
$pop = new nocc_imap();
}
catch (Exception $ex) {
$ev = new NoccException($ex->getMessage());
return($ev);
}
if ($pop->is_imap()) {
$mime = "To: $rcpt_to" . $conf->crlf . "Subject: " . $this->subject . $conf->crlf . $mime;
$copy_return = $pop->copytosentfolder($mime, $ev, $user_prefs->getSentFolderName());
if (NoccException::isException($ev)) {
return($ev);
}
}
}
if ($ev != true)
return (new NoccException('unable to send message, SMTP server unreachable'));
}
else { //if use SMTP server...
$smtp = new smtp();
if (!empty($smtp)) {
$smtp->smtp_server = $this->smtp_server;
$smtp->port = $this->smtp_port;
$smtp->from = $this->strip_comment($this->from);
$smtp->to = $this->strip_comment_array($this->to);
$smtp->cc = $this->strip_comment_array($this->cc);
$smtp->bcc = $this->strip_comment_array($this->bcc);
$smtp->subject = $this->subject;
$smtp->data = $mime;
$smtp_return = $smtp->send();
if (NoccException::isException($smtp_return)) {
return($smtp_return);
}
$copy_return = 1;
$user_prefs = NOCC_Session::getUserPrefs();
if ($user_prefs->getUseSentFolder() && $user_prefs->getSentFolderName() != "") {
// Copy email to Sent folder
//TODO: Optimize try block!
try {
$pop = new nocc_imap();
}
catch (Exception $ex) {
$ev = new NoccException($ex->getMessage());
return($ev);
}
if ($pop->is_imap()) {
$copy_return = $pop->copytosentfolder($smtp->data, $ev, $user_prefs->getSentFolderName());
if (NoccException::isException($ev)) {
return($ev);
}
}
}
return ($smtp_return && $copy_return);
}
else
return (0);
}
}
/**
* Use SMTP server to send the mail?
* @return boolean Use SMTP server?
*/
public function useSmtpServer() {
if (($this->smtp_server != '' && $this->smtp_port != '')) {
return true;
}
return false;
}
/**
* ...
*
* @param array $array
* @return array
* @access private
* @todo Rename!
*/
private function strip_comment_array($array) {
for ($i = 0; $i < count($array); $i++) {
$array[$i] = $this->strip_comment($array[$i]);
}
return $array;
}
/**
* ...
*
* @param string $address
* @return string
* @access private
* @todo Rename!
*/
private function strip_comment($address) {
$pos = strrpos($address, '<');
if ($pos === false) {
return '<'.$address.'>';
}
else {
return substr($address, $pos);
}
}
}