Map \wcf\system\mail\Mail to \wcf\system\email\Email
authorTim Düsterhus <duesterhus@woltlab.com>
Tue, 23 Oct 2018 17:59:32 +0000 (19:59 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Tue, 23 Oct 2018 18:00:22 +0000 (20:00 +0200)
see #2754

wcfsetup/install/files/lib/system/mail/DebugMailSender.class.php [deleted file]
wcfsetup/install/files/lib/system/mail/Mail.class.php
wcfsetup/install/files/lib/system/mail/MailSender.class.php [deleted file]
wcfsetup/install/files/lib/system/mail/PHPMailSender.class.php [deleted file]
wcfsetup/install/files/lib/system/mail/SMTPMailSender.class.php [deleted file]

diff --git a/wcfsetup/install/files/lib/system/mail/DebugMailSender.class.php b/wcfsetup/install/files/lib/system/mail/DebugMailSender.class.php
deleted file mode 100644 (file)
index e2cf923..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-namespace wcf\system\mail;
-use wcf\system\io\File;
-
-/**
- * DebugMailSender is a debug implementation of mailsender which writes emails in
- * a log file.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2018 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core\Data\Mail
- * @deprecated The Community Framework 2.x mail API is deprecated in favor of \wcf\system\email\*.
- */
-class DebugMailSender extends MailSender {
-       /**
-        * log file
-        * @var File
-        */
-       protected $log = null;
-       
-       /**
-        * Writes the given e-mail in a log file.
-        * 
-        * @param       Mail    $mail
-        */
-       public function sendMail(Mail $mail) {
-               if ($this->log === null) {
-                       $logFilePath = WCF_DIR . 'log/';
-                       $this->log = new File($logFilePath . 'mail.log', 'ab');
-               }
-               
-               $this->log->write(self::printMail($mail));
-       }
-       
-       /**
-        * Prints the given mail.
-        * 
-        * @param       Mail    $mail
-        * @return      string
-        */
-       protected static function printMail(Mail $mail) {
-               return  "Date: ".gmdate('r')."\n".
-                       "To: ".$mail->getToString()."\n".
-                       "Subject: ".$mail->getSubject()."\n".
-                       $mail->getHeader()."\n".
-                       "Attachments: ".print_r($mail->getAttachments(), true)."\n\n".
-                       $mail->getMessage()."\n\n";
-       }
-}
index c4f07f725ca81fb37b21de3a25d831f680847af6..5a2600132ff9cf6df7d8b6543a421f13fbe253bc 100644 (file)
@@ -1,6 +1,11 @@
 <?php
 namespace wcf\system\mail;
 use wcf\data\language\Language;
+use wcf\system\email\mime\AttachmentMimePart;
+use wcf\system\email\mime\MimePartFacade;
+use wcf\system\email\mime\PlainTextMimePart;
+use wcf\system\email\Email;
+use wcf\system\email\Mailbox;
 use wcf\system\WCF;
 use wcf\util\FileUtil;
 
@@ -20,84 +25,30 @@ class Mail {
         */
        public static $lineEnding = "\n";
        
-       /**
-        * mail header
-        * @var string
-        */
-       protected $header = '';
-       
-       /**
-        * boundary for multipart/mixed mail
-        * @var string
-        */
-       protected $boundary = '';
-       
-       /**
-        * mail content mime type
-        * @var string
-        */
-       protected $contentType = "text/plain";
-       
-       /**
-        * mail recipients
-        * @var string[]
-        */
-       protected $to = [];
-       
-       /**
-        * mail subject
-        * @var string
-        */
-       protected $subject = '';
-       
        /**
         * mail message
         * @var string
         */
        protected $message = '';
        
-       /**
-        * mail sender
-        * @var string
-        */
-       protected $from = '';
-       
-       /**
-        * mail carbon copy
-        * @var string[]
-        */
-       protected $cc = [];
-       
-       /**
-        * mail blind carbon copy
-        * @var string[]
-        */
-       protected $bcc = [];
-       
        /**
         * mail attachments
         * @var array
         */
        protected $attachments = [];
        
-       /**
-        * priority of the mail
-        * @var integer
-        */
-       protected $priority = 3;
-       
-       /**
-        * mail body
-        * @var string
-        */
-       protected $body = '';
-       
        /**
         * mail language
         * @var Language
         */
        protected $language = null;
        
+       /**
+        * the underlying email object
+        * @var Email
+        */
+       protected $email = null;
+       
        /**
         * Creates a new Mail object.
         * 
@@ -112,7 +63,7 @@ class Mail {
         * @param       string          $header
         */
        public function __construct($to = '', $subject = '', $message = '', $from = '', $cc = '', $bcc = '', $attachments = [], $priority = '', $header = '') {
-               $this->setBoundary();
+               $this->email = new Email();
                
                if (empty($from)) $from = [MAIL_FROM_NAME => MAIL_FROM_ADDRESS];
                if (empty($priority)) $priority = 3;
@@ -121,7 +72,7 @@ class Mail {
                $this->setSubject($subject);
                $this->setMessage($message);
                $this->setPriority($priority);
-               $this->setHeader($header);
+               if ($header != '') $this->setHeader($header);
                
                if (!empty($to)) $this->addTo($to);
                if (!empty($cc)) $this->addCC($cc);
@@ -131,122 +82,65 @@ class Mail {
        }
        
        /**
-        * Creates and returns a basic header for the email.
+        * Returns the underlying email object
         * 
-        * @return      string          mail header
+        * @return      Email
         */
-       public function getHeader() {
-               if (!empty($this->header)) {
-                       $this->header = preg_replace('%(\r\n|\r|\n)%', self::$lineEnding, $this->header);
-               }
+       public function getEmail() {
+               $attachments = array_map(function ($attachment) {
+                       return new AttachmentMimePart($attachment['path'], $attachment['name']);
+               }, $this->attachments);
                
-               $this->header .=
-                       'X-Priority: 3'.self::$lineEnding
-                       .'X-Mailer: WoltLab Suite Mail Package'.self::$lineEnding
-                       .'From: '.$this->getFrom().self::$lineEnding
-                       .($this->getCCString() != '' ? 'CC:'.$this->getCCString().self::$lineEnding : '')
-                       .($this->getBCCString() != '' ? 'BCC:'.$this->getBCCString().self::$lineEnding : '');
-                       
-               if (count($this->getAttachments())) {
-                       $this->header .= 'Content-Transfer-Encoding: 8bit'.self::$lineEnding;
-                       $this->header .= 'Content-Type: multipart/mixed;'.self::$lineEnding;
-                       $this->header .= "\tboundary=".'"'.$this->getBoundary().'";'.self::$lineEnding;
-               }
-               else {
-                       $this->header .= 'Content-Transfer-Encoding: 8bit'.self::$lineEnding;
-                       $this->header .= 'Content-Type: '.$this->getContentType().'; charset=UTF-8'.self::$lineEnding;
-               }
+               $text = new PlainTextMimePart($this->message);
                
-               $this->header .= 'MIME-Version: 1.0'.self::$lineEnding;
+               $this->email->setBody(new MimePartFacade([$text], $attachments));
                
-               return $this->header;
+               return $this->email;
        }
        
        /**
-        * Creates and returns the recipients list (TO, CC, BCC).
-        * 
-        * @param       boolean         $withTo
-        * @return      string
+        * @throws \BadMethodCallException always
+        */
+       public function getHeader() {
+               throw new \BadMethodCallException('This method is unavailable.');
+       }
+       
+       /**
+        * @throws \BadMethodCallException always
         */
        public function getRecipients($withTo = false) {
-               $recipients = '';
-               if ($withTo && $this->getToString() != '') $recipients .= 'TO:'.$this->getToString().self::$lineEnding;
-               if ($this->getCCString() != '') $recipients .= 'CC:'.$this->getCCString().self::$lineEnding;
-               if ($this->getBCCString() != '') $recipients .= 'BCC:'.$this->getBCCString().self::$lineEnding;
-               return $recipients;
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Creates and returned the body (Message, Attachments) for the email.
-        * 
-        * @return      string          mail body
+        * @throws \BadMethodCallException always
         */
        public function getBody() {
-               $counter = 1;
-               $this->body = '';
-               
-               if (count($this->getAttachments())) {
-                       // add message
-                       $this->body .= '--'.$this->getBoundary().self::$lineEnding;
-                       $this->body .= 'Content-Type: '.$this->getContentType().'; charset="UTF-8"'.self::$lineEnding;
-                       $this->body .= 'Content-Transfer-Encoding: 8bit'.self::$lineEnding;
-                       $this->body .= self::$lineEnding;
-                       
-                       // wrap lines after 70 characters
-                       $this->body .= wordwrap($this->getMessage(), 70);
-                       $this->body .= self::$lineEnding.self::$lineEnding;
-                       $this->body .= '--'.$this->getBoundary().self::$lineEnding;
-                       
-                       // add attachments
-                       foreach ($this->getAttachments() as $attachment) {
-                               $fileName = $attachment['name'];
-                               $path = $attachment['path'];
-                               
-                               // download file
-                               if (FileUtil::isURL($path)) {
-                                       $tmpPath = FileUtil::getTemporaryFilename('mailAttachment_');
-                                       if (!@copy($path, $tmpPath)) continue;
-                                       $path = $tmpPath;
-                               }
-                               
-                               // get file contents
-                               $data = @file_get_contents($path);
-                               $data = chunk_split(base64_encode($data), 70, self::$lineEnding);
-                               
-                               $this->body .= 'Content-Type: application/octetstream; name="'.$fileName.'"'.self::$lineEnding;
-                               $this->body .= 'Content-Transfer-Encoding: base64'.self::$lineEnding;
-                               $this->body .= 'Content-Disposition: attachment; filename="'.$fileName.'"'.self::$lineEnding.self::$lineEnding;
-                               $this->body .= $data.self::$lineEnding.self::$lineEnding;
-                               
-                               if ($counter < count($this->getAttachments())) $this->body .= '--'.$this->getBoundary().self::$lineEnding;
-                               $counter++;
-                       }
-                       
-                       $this->body .= self::$lineEnding.'--'.$this->getBoundary().'--';
-               }
-               else {
-                       $this->body .= $this->getMessage();
-               }
-               return $this->body;
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Builds a formatted address: "$name" <$email>.
-        * 
-        * @param       string          $name
-        * @param       string          $email
-        * @param       boolean         $encodeName
-        * @return      string
+        * @throws \BadMethodCallException always
         */
        public static function buildAddress($name, $email, $encodeName = true) {
-               return $email;
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Sends this mail.
+        * @see Email::send()
         */
        public function send() {
-               MailSender::getInstance()->sendMail($this);
+               $this->getEmail()->send();
+       }
+       
+       protected function makeMailbox($email, $name = null) {
+               if ($name) {
+                       return new Mailbox($email, $name, $this->getLanguage());
+               }
+               if (preg_match('~^(.+) <([^>]+)>$~', $email, $matches)) {
+                       return new Mailbox($matches[2], $matches[1], $this->getLanguage());
+               }
+               return new Mailbox($email, null, $this->getLanguage());
        }
        
        /**
@@ -257,48 +151,40 @@ class Mail {
        public function addTo($to) {
                if (is_array($to)) {
                        foreach ($to as $name => $recipient) {
-                               $this->to[] = self::buildAddress($name, $recipient);
+                               $this->email->addRecipient($this->makeMailbox($recipient, $name));
                        }
                }
                else {
-                       $this->to[] = $to;
+                       $this->email->addRecipient($this->makeMailbox($to));
                }
        }
        
        /**
-        * Returns the recipients of this mail.
-        * 
-        * @return      mixed
+        * @throws \BadMethodCallException always
         */
        public function getTo() {
-               return $this->to;
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Returns the list of recipients.
-        * 
-        * @return      string
+        * @throws \BadMethodCallException always
         */
        public function getToString() {
-               return implode(', ', $this->to);
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Sets the subject of this mail.
-        * 
-        * @param       string          $subject
+        * @see Email::setSubject()
         */
        public function setSubject($subject) {
-               $this->subject = $subject;
+               $this->email->setSubject($subject);
        }
        
        /**
-        * Returns the subject of this mail.
-        * 
-        * @return      string
+        * @see Email::getSubject()
         */
        public function getSubject() {
-               return $this->subject;
+               return $this->email->getSubject();
        }
        
        /**
@@ -311,35 +197,29 @@ class Mail {
        }
        
        /**
-        * Returns the message of this mail.
-        * 
-        * @return      string
+        * @throws \BadMethodCallException always
         */
        public function getMessage() {
-               return preg_replace('%(\r\n|\r|\n)%', self::$lineEnding, $this->message . (MAIL_SIGNATURE ? self::$lineEnding . self::$lineEnding . '-- ' . self::$lineEnding . $this->getLanguage()->get(MAIL_SIGNATURE) : ''));
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Sets the sender of this mail.
-        * 
-        * @param       mixed           $from
+        * @see Email::setSender()
         */
        public function setFrom($from) {
                if (is_array($from)) {
-                       $this->from = self::buildAddress(key($from), current($from));
+                       $this->email->setSender($this->makeMailbox(current($from), key($from)));
                }
                else {
-                       $this->from = $from;
+                       $this->email->setSender($this->makeMailbox($from));
                }
        }
        
        /**
-        * Returns the sender of this mail.
-        * 
-        * @return      string
+        * @throws \BadMethodCallException always
         */
        public function getFrom() {
-               return $this->from;
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
@@ -350,30 +230,26 @@ class Mail {
        public function addCC($cc) {
                if (is_array($cc)) {
                        foreach ($cc as $name => $recipient) {
-                               $this->cc[] = self::buildAddress($name, $recipient);
+                               $this->email->addRecipient($this->makeMailbox($recipient, $name), 'cc');
                        }
                }
                else {
-                       $this->cc[] = $cc;
+                       $this->email->addRecipient($this->makeMailbox($cc), 'cc');
                }
        }
        
        /**
-        * Returns the carbon copy recipients of this mail.
-        * 
-        * @return      mixed
+        * @throws \BadMethodCallException always
         */
        public function getCC() {
-               return $this->cc;
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Returns the carbon copy recipients of this mail as string.
-        * 
-        * @return      string
+        * @throws \BadMethodCallException always
         */
        public function getCCString() {
-               return implode(', ', $this->cc);
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
@@ -384,30 +260,26 @@ class Mail {
        public function addBCC($bcc) {
                if (is_array($bcc)) {
                        foreach ($bcc as $name => $recipient) {
-                               $this->bcc[] = self::buildAddress($name, $recipient);
+                               $this->email->addRecipient($this->makeMailbox($recipient, $name), 'bcc');
                        }
                }
                else {
-                       $this->bcc[] = $bcc;
+                       $this->email->addRecipient($this->makeMailbox($bcc), 'bcc');
                }
        }
        
        /**
-        * Returns the blind carbon copy recipients of this mail.
-        * 
-        * @return      mixed
+        * @throws \BadMethodCallException always
         */
        public function getBCC() {
-               return $this->bcc;
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Returns the blind carbon copy recipients of this mail as string.
-        * 
-        * @return      string
+        * @throws \BadMethodCallException always
         */
        public function getBCCString() {
-               return implode(', ', $this->bcc);
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
@@ -444,61 +316,35 @@ class Mail {
         * @param       integer         $priority
         */
        public function setPriority($priority) {
-               $this->priority = $priority;
+               $this->email->addHeader('x-priority', $priority);
        }
        
        /**
-        * Returns the priority of the mail
-        * 
-        * @return      integer
+        * @throws \BadMethodCallException always
         */
        public function getPriority() {
-               return $this->priority;
-       }
-       
-       /**
-        * Creates a boundary for multipart/mixed mail.
-        */
-       protected function setBoundary() {
-               $this->boundary = "==Multipart_Boundary_x".bin2hex(\random_bytes(20))."x";
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Returns the created boundary.
-        * 
-        * @return      string
-        */
-       protected function getBoundary() {
-               return $this->boundary;
-       }
-       
-       /**
-        * Returns the content type.
-        * 
-        * @return      string
+        * @throws \BadMethodCallException always
         */
        public function getContentType() {
-               return $this->contentType;
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Sets the content type.
-        * 
-        * @param       string          $contentType
+        * @throws \BadMethodCallException always
         */
        public function setContentType($contentType) {
-               $this->contentType = $contentType;
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
-        * Sets an additional header.
-        * 
-        * @param       string          $header
+        * @throws \BadMethodCallException always
         */
        public function setHeader($header) {
-               if (!empty($header)) {
-                       $this->header .= $header.self::$lineEnding;
-               }
+               throw new \BadMethodCallException('This method is unavailable.');
        }
        
        /**
diff --git a/wcfsetup/install/files/lib/system/mail/MailSender.class.php b/wcfsetup/install/files/lib/system/mail/MailSender.class.php
deleted file mode 100644 (file)
index 9a8fa5d..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-namespace wcf\system\mail;
-
-/**
- * Mailsender sends emails.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2018 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core\Data\Mail
- * @deprecated The Community Framework 2.x mail API is deprecated in favor of \wcf\system\email\*.
- */
-abstract class MailSender {
-       /**
-        * unique mail server instance
-        * @var MailSender
-        */
-       protected static $instance = null;
-       
-       /**
-        * Returns the default mail sender.
-        * 
-        * @return      MailSender
-        */
-       public static function getInstance() {
-               if (self::$instance === null) {
-                       switch (MAIL_SEND_METHOD) {
-                               case 'php':
-                                       self::$instance = new PHPMailSender();
-                               break;
-                               
-                               case 'smtp':
-                                       self::$instance = new SMTPMailSender();
-                               break;
-                               
-                               case 'debug':
-                                       self::$instance = new DebugMailSender();
-                               break;
-                       }
-               }
-               
-               return self::$instance;
-       }
-       
-       /**
-        * Sends an e-mail.
-        * 
-        * @param       Mail    $mail
-        */
-       abstract public function sendMail(Mail $mail);
-}
diff --git a/wcfsetup/install/files/lib/system/mail/PHPMailSender.class.php b/wcfsetup/install/files/lib/system/mail/PHPMailSender.class.php
deleted file mode 100644 (file)
index 77597b3..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-namespace wcf\system\mail;
-
-/**
- * Sends a mail with the php mail function.
- * 
- * @author     Alexander Ebert
- * @copyright  2001-2018 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core\Data\Mail
- * @deprecated The Community Framework 2.x mail API is deprecated in favor of \wcf\system\email\*.
- */
-class PHPMailSender extends MailSender {
-       /**
-        * @inheritDoc
-        */
-       public function sendMail(Mail $mail) {
-               if (MAIL_USE_F_PARAM) return @mb_send_mail($mail->getToString(), $mail->getSubject(), $mail->getBody(), $mail->getHeader(), '-f'.MAIL_FROM_ADDRESS);
-               else return @mb_send_mail($mail->getToString(), $mail->getSubject(), $mail->getBody(), $mail->getHeader());
-       }
-}
diff --git a/wcfsetup/install/files/lib/system/mail/SMTPMailSender.class.php b/wcfsetup/install/files/lib/system/mail/SMTPMailSender.class.php
deleted file mode 100644 (file)
index e87b15b..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-<?php
-namespace wcf\system\mail;
-use wcf\system\exception\SystemException;
-use wcf\system\io\RemoteFile;
-use wcf\util\StringUtil;
-
-/**
- * Sends a Mail with a connection to a smtp server.
- * 
- * @author     Tim Duesterhus, Alexander Ebert
- * @copyright  2001-2018 WoltLab GmbH
- * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @package    WoltLabSuite\Core\Data\Mail
- * @deprecated The Community Framework 2.x mail API is deprecated in favor of \wcf\system\email\*.
- */
-class SMTPMailSender extends MailSender {
-       /**
-        * smtp connection
-        * @var RemoteFile
-        */
-       protected $connection = null;
-       
-       /**
-        * last received status code
-        * @var string
-        */
-       protected $statusCode = '';
-       
-       /**
-        * last received status message
-        * @var string
-        */
-       protected $statusMsg = '';
-       
-       /**
-        * mail recipients
-        * @var array
-        */
-       protected $recipients = [];
-       
-       /**
-        * Creates a new SMTPMailSender object.
-        */
-       public function __construct() {
-               Mail::$lineEnding = "\r\n";
-       }
-       
-       /**
-        * Destroys the SMTPMailSender object.
-        */
-       public function __destruct() {
-               $this->disconnect();
-       }
-       
-       /**
-        * Connects to the smtp-server
-        */
-       protected function connect() {
-               // connect
-               $this->connection = new RemoteFile(MAIL_SMTP_HOST, MAIL_SMTP_PORT);
-               $this->getSMTPStatus();
-               if ($this->statusCode != 220) {
-                       throw new SystemException($this->formatError("can not connect to '".MAIL_SMTP_HOST.":".MAIL_SMTP_PORT."'"));
-               }
-               
-               $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : '';
-               if (empty($host)) {
-                       $host = gethostname();
-                       if ($host === false) {
-                               $host = 'localhost';
-                       }
-               }
-               
-               // send ehlo
-               $this->write('EHLO '.$host);
-               $extensions = explode(Mail::$lineEnding, $this->read());
-               $this->getSMTPStatus(array_shift($extensions));
-               if ($this->statusCode == 250) {
-                       $extensions = array_map(function($element) {
-                               return strtolower(substr($element, 4));
-                       }, $extensions);
-                       
-                       if ($this->connection->hasTLSSupport() && in_array('starttls', $extensions)) {
-                               $this->write('STARTTLS');
-                               $this->getSMTPStatus();
-                               
-                               if ($this->statusCode != 220) {
-                                       throw new SystemException($this->formatError("cannot enable STARTTLS, though '".MAIL_SMTP_HOST.":".MAIL_SMTP_PORT."' advertised it"));
-                               }
-                               
-                               if (!$this->connection->setTLS(true)) {
-                                       throw new SystemException('enabling TLS failed');
-                               }
-                               
-                               // repeat EHLO
-                               $this->write('EHLO '.$host);
-                               $extensions = explode(Mail::$lineEnding, $this->read());
-                               $this->getSMTPStatus(array_shift($extensions));
-                               
-                               if ($this->statusCode != 250) {
-                                       throw new SystemException($this->formatError("could not EHLO after enabling STARTTLS at '".MAIL_SMTP_HOST.":".MAIL_SMTP_PORT."'"));
-                               }
-                       }
-                       
-                       // do authentication
-                       if (MAIL_SMTP_USER != '' || MAIL_SMTP_PASSWORD != '') {
-                               $this->auth();
-                       }
-               }
-               else {
-                       // send helo
-                       $this->write('HELO '.$host);
-                       $this->getSMTPStatus();
-                       if ($this->statusCode != 250) {
-                               throw new SystemException($this->formatError("can not connect to '".MAIL_SMTP_HOST.":".MAIL_SMTP_PORT."'"));
-                       }
-               }
-       }
-       
-       /**
-        * Formats a smtp error message.
-        * 
-        * @param       string          $message
-        * @return      string
-        */
-       protected function formatError($message) {
-               return $message.': '.$this->statusMsg.' ('.$this->statusCode.')';
-       }
-       
-       /**
-        * Does the authentification of the client on the server
-        */
-       protected function auth() {
-               // init authentication
-               $this->write('AUTH LOGIN');
-               $this->getSMTPStatus();
-               
-               // checks if auth is supported
-               if ($this->statusCode != 334) {
-                       throw new SystemException($this->formatError("smtp mail server '".MAIL_SMTP_HOST.":".MAIL_SMTP_PORT."' does not support user authentication"));
-               }
-               
-               // sending user information to smtp-server
-               $this->write(base64_encode(MAIL_SMTP_USER));
-               $this->getSMTPStatus();
-               if ($this->statusCode != 334) {
-                       throw new SystemException($this->formatError("unknown smtp user '".MAIL_SMTP_USER."'"));
-               }
-               
-               $this->write(base64_encode(MAIL_SMTP_PASSWORD));
-               $this->getSMTPStatus();
-               if ($this->statusCode != 235) {
-                       throw new SystemException($this->formatError("invalid password for smtp user '".MAIL_SMTP_USER."'"));
-               }
-       }
-       
-       /**
-        * @inheritDoc
-        */
-       public function sendMail(Mail $mail) {
-               $this->recipients = [];
-               if (count($mail->getTo()) > 0) $this->recipients = $mail->getTo();
-               if (count($mail->getCC()) > 0) $this->recipients = array_merge($this->recipients, $mail->getCC());
-               if (count($mail->getBCC())> 0) $this->recipients = array_merge($this->recipients, $mail->getBCC());
-               
-               // apply connection
-               if ($this->connection === null) {
-                       $this->connect();
-               }
-               
-               // send mail
-               $this->write('MAIL FROM:<'.$mail->getFrom().'>');
-               $this->getSMTPStatus();
-               if ($this->statusCode != 250) {
-                       $this->abort();
-                       throw new SystemException($this->formatError("wrong from format '".$mail->getFrom()."'"));
-               }
-               
-               // recipients
-               $recipientCounter = 0;
-               foreach ($this->recipients as $recipient) {
-                       $this->write('RCPT TO:<'.$recipient.'>');
-                       $this->getSMTPStatus();
-                       if ($this->statusCode != 250 && $this->statusCode != 251) {
-                               if ($this->statusCode < 550) {
-                                       $this->abort();
-                                       throw new SystemException($this->formatError("wrong recipient format '".$recipient."'"));
-                               }
-                               continue;
-                       }
-                       $recipientCounter++;
-               }
-               if (!$recipientCounter) {
-                       $this->abort();
-                       return;
-               }
-               
-               // data
-               $this->write("DATA");
-               $this->getSMTPStatus();
-               if ($this->statusCode != 354 && $this->statusCode != 250) {
-                       $this->abort();
-                       throw new SystemException($this->formatError("smtp error"));
-               }
-               
-               $serverName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
-               if (empty($serverName)) {
-                       $serverName = gethostname();
-                       if ($serverName === false) {
-                               $serverName = 'localhost';
-                       }
-               }
-               
-               $header =
-                       "Date: ".gmdate('r').Mail::$lineEnding
-                       ."To: ".$mail->getToString().Mail::$lineEnding
-                       ."Message-ID: <".md5(uniqid())."@".$serverName.">".Mail::$lineEnding
-                       ."Subject: ".Mail::encodeMIMEHeader($mail->getSubject()).Mail::$lineEnding
-                       .$mail->getHeader();
-               
-               $this->write($header);
-               $this->write("");
-               $lines = explode(Mail::$lineEnding, $mail->getBody());
-               foreach ($lines as $line) {
-                       // 4.5.2 Transparency
-                       // o  Before sending a line of mail text, the SMTP client checks the
-                       //    first character of the line.  If it is a period, one additional
-                       //    period is inserted at the beginning of the line.
-                       if (StringUtil::startsWith($line, '.')) $line = '.'.$line;
-                       $this->write($line);
-               }
-               $this->write(".");
-               
-               $this->getSMTPStatus();
-               if ($this->statusCode != 250) {
-                       $this->abort();
-                       throw new SystemException($this->formatError("message sending failed"));
-               }
-       }
-       
-       /**
-        * Disconnects the Client-Server connection
-        */
-       public function disconnect() {
-               if ($this->connection === null) {
-                       return;
-               }
-               
-               $this->write("QUIT");
-               $this->read();
-               $this->connection->close();
-               $this->connection = null;
-       }
-       
-       /**
-        * Reads the Information which the Server sends back.
-        * 
-        * @return      string
-        */
-       protected function read() {
-               $result = '';
-               while ($read = $this->connection->gets()) {
-                       $result .= $read;
-                       if (substr($read, 3, 1) == " ") break;
-               }
-               
-               return $result;
-       }
-       
-       /**
-        * Aborts the current process. This is needed in case a new mail should be
-        * sent after a exception has occured
-        */
-       protected function abort() {
-               $this->write("RSET");
-               $this->read(); // read response, but do not care about status here
-       }
-       
-       /**
-        * Extracts error code and message from a server message.
-        * 
-        * @param       string          $data
-        */
-       protected function getSMTPStatus($data = null) {
-               if ($data === null) $data = $this->read();
-               $this->statusCode = intval(substr($data, 0, 3));
-               $this->statusMsg = substr($data, 4);
-       }
-       
-       /**
-        * Sends Information to the smtp-Server
-        * 
-        * @param       string          $data
-        */
-       protected function write($data) {
-               $this->connection->puts($data.Mail::$lineEnding);
-       }
-}