Beispiel #1
0
 /**
  * SMTP Constructor
  *
  * @param array $config Configuration for initialize the class
  *
  * @throws Exception\ServerFromAddressInvalid
  * @throws Exception\ServerReplyToAddressInvalid
  * @throws Exception\ServerReturnToAddressInvalid
  * @throws Exception\ServerErrorToAddressInvalid
  * @throws Exception\NoServerSpecified
  */
 public function __construct(array &$config)
 {
     $typeVerified = array();
     $cp = new ConfigParser($config, static::$defaultConfig);
     $version = Framework::getVersion();
     $senderIP = IP::joinIP(Framework::core('request')->getClientInfo('ipArray'), true);
     $this->config['Handler'] = $version['App'] . ' ' . $version['Ver'];
     if ($cp->isEmpty('Servers')) {
         throw new Exception\NoServerSpecified();
     }
     $this->config['Temp'] = PathParser::get($cp->getValid('TempFilesDir', function ($val) {
         return is_dir($val);
     }, sys_get_temp_dir()));
     $servers = $cp->get('Servers');
     if ($cp->has('SelectMethod')) {
         switch ($cp->get('SelectMethod')) {
             case 'SelectMethod':
                 shuffle($servers);
                 break;
         }
     }
     foreach ($servers as $key => $val) {
         $serverCP = new ConfigParser($val, static::$defaultServerConfig);
         $mailUserName = $serverCP->get('Username');
         $mailDefaultFrom = strpos($mailUserName, '@') !== false ? $mailUserName : $mailUserName . '@' . $serverCP->get('Host');
         $emailFrom = $serverCP->getValid('From', function ($val) {
             if (empty($val)) {
                 return false;
             }
             if (!Validator::check($val, 'email')) {
                 throw new Exception\ServerFromAddressInvalid($val);
             }
             return true;
         }, $mailDefaultFrom);
         $this->config['Servers'][$key] = array('Host' => $serverCP->get('Host'), 'Port' => $serverCP->get('Port'), 'Type' => $serverCP->getValid('Type', function ($val) use(&$typeVerified) {
             if (empty($val)) {
                 return false;
             }
             if (isset($typeVerified[$val])) {
                 return true;
             }
             if (!isset(static::$operators[$val])) {
                 throw new Exception\UnknownServerType($val);
             }
             $optClass = static::$operators[$val];
             if (!class_exists($optClass)) {
                 throw new Exception\OperatorClassNotFound($optClass, $val);
             }
             $parents = class_parents($optClass);
             if (!isset($parents)) {
                 throw new Exception\OperatorExtendsInvalid($optClass);
             }
             $typeVerified[$val] = true;
             return true;
         }, 'General'), 'Timeout' => $serverCP->get('Timeout'), 'Retry' => $serverCP->get('Retry'), 'Username' => $mailUserName, 'Password' => $serverCP->get('Password'), 'Handler' => $this->config['Handler'], 'ScreenName' => $serverCP->get('ScreenName', $serverCP->get('Username')), 'From' => $emailFrom, 'ReplyTo' => $serverCP->getValid('ReplyTo', function ($val) {
             if (empty($val)) {
                 return false;
             }
             if (!Validator::check($val, 'email')) {
                 throw new Exception\ServerReplyToAddressInvalid($val);
             }
             return true;
         }, $emailFrom), 'ReturnTo' => $serverCP->getValid('ReturnTo', function ($val) {
             if (empty($val)) {
                 return false;
             }
             if (!Validator::check($val, 'email')) {
                 throw new Exception\ServerReturnToAddressInvalid($val);
             }
             return true;
         }, $emailFrom), 'ErrorTo' => $serverCP->getValid('ReturnTo', function ($val) {
             if (empty($val)) {
                 return false;
             }
             if (!Validator::check($val, 'email')) {
                 throw new Exception\ServerErrorToAddressInvalid($val);
             }
             return true;
         }, $emailFrom), 'SignCert' => PathParser::get($serverCP->getValid('SignatureCert', function ($val) {
             if (empty($val)) {
                 return false;
             }
             if (!is_readable($val)) {
                 throw new Exception\ServerSignCertNotReadable($val);
             }
             return true;
         }, '')), 'SignKey' => PathParser::get($serverCP->getValid('SignatureKey', function ($val) {
             if (empty($val)) {
                 return false;
             }
             if (!is_readable($val)) {
                 throw new Exception\ServerSignKeyNotReadable($val);
             }
             return true;
         }, '')), 'SignPass' => $serverCP->get('SignaturePass'), 'SignChain' => PathParser::get($serverCP->getValid('SignatureChain', function ($val) {
             if (empty($val)) {
                 return false;
             }
             if (!is_readable($val)) {
                 throw new Exception\ServerSignChainNotReadable($val);
             }
             return true;
         }, '')), 'SenderIP' => $senderIP);
     }
 }
Beispiel #2
0
 /**
  * Constructor for the MIME mail builder
  *
  * @param array $mail The email in array
  * @param array $config Configuration
  */
 public function __construct(array $mail, array &$config)
 {
     global $_SERVER;
     $senderHost = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
     $this->config = $config;
     $appInfo = Framework::getVersion();
     $mailContent = array('Title' => isset($mail['Title']) ? $mail['Title'] : null, 'Message' => isset($mail['Message']) ? $mail['Message'] : null);
     $this->mail['From'] = '=?UTF-8?B?' . base64_encode($mail['ScreenName']) . '?= <' . $mail['From'] . '>';
     $this->mail['Subject'] = '=?UTF-8?B?' . rtrim(base64_encode($mailContent['Title'] ? $mailContent['Title'] : '(Untitled)'), '=') . '?=';
     // Parse mail body
     $mail['Subject'] = $this->mail['Subject'];
     $mail['Body'] = chunk_split(base64_encode($mailContent['Message']) . '?=', 76, "\r\n");
     $mail['AltBody'] = chunk_split(base64_encode(strip_tags(str_replace('</', "\r\n</", $mailContent['Message']))) . '?=', 76, "\r\n");
     // Make mail header
     $this->addLine('MIME-Version', '1.0');
     $this->addLine('User-Agent', $appInfo['App'] . ' ' . $appInfo['Ver'] . ' (' . $appInfo['Base'] . ')');
     $this->addLine('X-Priority', '3');
     $this->addLine('X-MSMail-Priority', 'Normal');
     $this->addLine('X-Mailer', $appInfo['App'] . ' ' . $appInfo['Ver'] . ' (' . $appInfo['Base'] . ')');
     $this->addLine('X-MimeOLE', $appInfo['Base'] . ' Mailer OLE');
     $this->addLine('X-AntiAbuse', 'This header was added to track abuse, please include it with any abuse report');
     $this->addLine('X-AntiAbuse', 'Primary Hostname - ' . $senderHost);
     $this->addLine('X-AntiAbuse', 'Original Domain - ' . $senderHost);
     $this->addLine('X-AntiAbuse', 'Originator/Caller UID/GID - [' . trim($senderHost . ' ' . $mail['SenderIP']) . '] / [' . trim($senderHost . ' ' . $mail['SenderIP']) . ']');
     $this->addLine('X-AntiAbuse', 'Sender Address Domain - ' . $senderHost);
     // Mail title
     $this->addLine('Subject', $mail['Subject']);
     // Addresses
     $this->addLine('From', $this->mail['From']);
     $this->addLine('To', 'undisclosed-recipients:;');
     $this->addLine('Return-Path', '<' . $mail['ReturnTo'] . '>');
     $this->addLine('Reply-To', '<' . $mail['ReplyTo'] . '>');
     $this->addLine('Errors-To', '<' . $mail['ErrorTo'] . '>');
     $this->addLine('Date', date('D, d M y H:i:s O', Framework::TIME));
     $this->addLine('Message-ID', md5($mail['AltBody'] . (string) $this->getFactor() . time()) . '@' . (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'));
     // Ready content for boundary check. Combine all content
     // strings to one line, then check if the boundary existed.
     $checkContent = $mail['Subject'] . $mail['Body'] . $mail['AltBody'];
     while (true) {
         $this->mail['Boundary'] = '#' . $this->getFactor() . '$';
         $this->mail['BoundarySpliter'] = '--' . $this->mail['Boundary'];
         $this->mail['BoundarySpliterEnd'] = $this->mail['BoundarySpliter'] . '--';
         if (strpos($checkContent, $this->mail['Boundary']) === false) {
             break;
         }
     }
     $this->addLine('Content-Type', 'multipart/alternative; boundary="' . $this->mail['Boundary'] . '"');
     // Make mail body
     $this->addRaw('');
     // Make space
     $this->addRaw('This MIME email produced by ' . $appInfo['Base'] . ' Mailer for ' . $senderHost . '.');
     $this->addRaw('If you have any problem reading this email, please contact ' . $mail['ReturnTo'] . ' for help.');
     $this->addRaw('');
     // Primary content
     $this->addRaw($this->mail['BoundarySpliter']);
     $this->addLine('Content-Type', 'text/plain; charset=utf-8');
     $this->addLine('Content-Transfer-Encoding', 'base64');
     $this->addRaw('');
     $this->addRaw($mail['AltBody']);
     $this->addRaw('');
     $this->addRaw($this->mail['BoundarySpliter']);
     $this->addLine('Content-Type', 'text/html; charset=utf-8');
     $this->addLine('Content-Transfer-Encoding', 'base64');
     $this->addRaw('');
     $this->addRaw($mail['Body']);
     $this->addRaw('');
     $this->addRaw($this->mail['BoundarySpliterEnd']);
 }
 /**
  * SMTP initializer
  *
  * @param array $cfg Configuration for initialize the class
  *
  * @return bool Return true when success, or false when fail
  */
 public static function init(array $cfg = array())
 {
     $version = array();
     $senderIP = '';
     if (empty(static::$config)) {
         $version = Framework::getVersion();
         $senderIP = IP::joinIP(Framework::core('request')->getClientInfo('ipArray'), true);
         static::$config['Handler'] = $version['App'] . ' ' . $version['Ver'];
         if (isset($cfg['Servers']) && is_array($cfg['Servers'])) {
             if (isset($cfg['SelectMethod']) && $cfg['SelectMethod'] == 'Random') {
                 shuffle($cfg['Servers']);
             }
             foreach ($cfg['Servers'] as $key => $val) {
                 static::$config['Servers'][$key] = array('Host' => isset($val['Host']) ? $val['Host'] : 'localhost', 'Port' => isset($val['Port']) ? $val['Port'] : 25, 'Type' => isset($val['Type']) ? $val['Type'] : 'general', 'Timeout' => isset($val['Timeout']) ? $val['Timeout'] : 1, 'Username' => isset($val['Username']) ? $val['Username'] : '', 'Password' => isset($val['Password']) ? $val['Password'] : '', 'Handler' => static::$config['Handler'], 'SenderIP' => $senderIP);
                 // Set poster screen name, this will be display on the receiver's list
                 if (isset($val['Screenname'])) {
                     static::$config['Servers'][$key]['Screenname'] = $val['Screenname'];
                 } else {
                     static::$config['Servers'][$key]['Screenname'] = static::$config['Servers'][$key]['Username'];
                 }
                 // Set MAIL FROM, this one must be set for future use
                 if (isset($val['From'])) {
                     if (Validator::check($val['From'], 'email')) {
                         static::$config['Servers'][$key]['From'] = $val['From'];
                     } else {
                         throw new Exception\ServerFromAddressInvaild($val['From']);
                     }
                 } else {
                     static::$config['Servers'][$key]['From'] = static::$config['Servers'][$key]['Username'] . '@' . static::$config['Servers'][$key]['Host'];
                 }
                 // Set REPLY TO
                 if (isset($val['ReplyTo'])) {
                     if (Validator::check($val['ReplyTo'], 'email')) {
                         static::$config['Servers'][$key]['ReplyTo'] = $val['ReplyTo'];
                     } else {
                         throw new Exception\ServerReplyToAddressInvaild($val['ReplyTo']);
                     }
                 } else {
                     static::$config['Servers'][$key]['ReplyTo'] = static::$config['Servers'][$key]['From'];
                 }
                 // Set RETURN TO
                 if (isset($val['ReturnTo'])) {
                     if (Validator::check($val['ReturnTo'], 'email')) {
                         static::$config['Servers'][$key]['ReturnTo'] = $val['ReturnTo'];
                     } else {
                         throw new Exception\ServerReturnToAddressInvaild($val['ReplyTo']);
                     }
                 } else {
                     static::$config['Servers'][$key]['ReturnTo'] = static::$config['Servers'][$key]['From'];
                 }
                 // Set ERROR TO
                 if (isset($val['ErrorTo'])) {
                     if (Validator::check($val['ErrorTo'], 'email')) {
                         static::$config['Servers'][$key]['ErrorTo'] = $val['ErrorTo'];
                     } else {
                         throw new Exception\ServerErrorToAddressInvaild($val['ErrorTo']);
                     }
                 } else {
                     static::$config['Servers'][$key]['ErrorTo'] = static::$config['Servers'][$key]['From'];
                 }
             }
             Framework::registerHook('response_finished', 'SMTP_Sending', function () {
                 static::sendMail();
             });
             Auther::init();
             return true;
         } else {
             throw new Exception\NoServerSpecified();
         }
     }
     return false;
 }