Packages

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
      • Adapters
      • Extensions
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Diagnostics
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
      • PhpGenerator
  • NetteModule
  • None
  • PHP

Classes

  • Mail
  • MailMimePart
  • SendmailMailer
  • SmtpMailer

Interfaces

  • IMailer

Exceptions

  • SmtpException
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  *
  6:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  * @package Nette\Mail
 11:  */
 12: 
 13: 
 14: 
 15: /**
 16:  * Sends emails via the SMTP server.
 17:  *
 18:  * @author     David Grudl
 19:  * @package Nette\Mail
 20:  */
 21: class SmtpMailer extends Object implements IMailer
 22: {
 23:     /** @var resource */
 24:     private $connection;
 25: 
 26:     /** @var string */
 27:     private $host;
 28: 
 29:     /** @var int */
 30:     private $port;
 31: 
 32:     /** @var string */
 33:     private $username;
 34: 
 35:     /** @var string */
 36:     private $password;
 37: 
 38:     /** @var string ssl | tls | (empty) */
 39:     private $secure;
 40: 
 41:     /** @var int */
 42:     private $timeout;
 43: 
 44: 
 45:     public function __construct(array $options = array())
 46:     {
 47:         if (isset($options['host'])) {
 48:             $this->host = $options['host'];
 49:             $this->port = isset($options['port']) ? (int) $options['port'] : NULL;
 50:         } else {
 51:             $this->host = ini_get('SMTP');
 52:             $this->port = (int) ini_get('smtp_port');
 53:         }
 54:         $this->username = isset($options['username']) ? $options['username'] : '';
 55:         $this->password = isset($options['password']) ? $options['password'] : '';
 56:         $this->secure = isset($options['secure']) ? $options['secure'] : '';
 57:         $this->timeout = isset($options['timeout']) ? (int) $options['timeout'] : 20;
 58:         if (!$this->port) {
 59:             $this->port = $this->secure === 'ssl' ? 465 : 25;
 60:         }
 61:     }
 62: 
 63: 
 64:     /**
 65:      * Sends email.
 66:      * @return void
 67:      */
 68:     public function send(Mail $mail)
 69:     {
 70:         $mail = clone $mail;
 71: 
 72:         $this->connect();
 73: 
 74:         if (($from = $mail->getHeader('Return-Path'))
 75:             || ($from = key($mail->getHeader('From'))))
 76:         {
 77:             $this->write("MAIL FROM:<$from>", 250);
 78:         }
 79: 
 80:         foreach (array_merge(
 81:             (array) $mail->getHeader('To'),
 82:             (array) $mail->getHeader('Cc'),
 83:             (array) $mail->getHeader('Bcc')
 84:         ) as $email => $name) {
 85:             $this->write("RCPT TO:<$email>", array(250, 251));
 86:         }
 87: 
 88:         $mail->setHeader('Bcc', NULL);
 89:         $data = $mail->generateMessage();
 90:         $this->write('DATA', 354);
 91:         $data = preg_replace('#^\.#m', '..', $data);
 92:         $this->write($data);
 93:         $this->write('.', 250);
 94: 
 95:         $this->write('QUIT', 221);
 96: 
 97:         $this->disconnect();
 98:     }
 99: 
100: 
101:     /**
102:      * Connects and authenticates to SMTP server.
103:      * @return void
104:      */
105:     private function connect()
106:     {
107:         $this->connection = @fsockopen( // intentionally @
108:             ($this->secure === 'ssl' ? 'ssl://' : '') . $this->host,
109:             $this->port, $errno, $error, $this->timeout
110:         );
111:         if (!$this->connection) {
112:             throw new SmtpException($error, $errno);
113:         }
114:         stream_set_timeout($this->connection, $this->timeout, 0);
115:         $this->read(); // greeting
116: 
117:         $self = isset($_SERVER['HTTP_HOST']) && preg_match('#^[\w.-]+\z#', $_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost';
118:         $this->write("EHLO $self");
119:         if ((int) $this->read() !== 250) {
120:             $this->write("HELO $self", 250);
121:         }
122: 
123:         if ($this->secure === 'tls') {
124:             $this->write('STARTTLS', 220);
125:             if (!stream_socket_enable_crypto($this->connection, TRUE, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
126:                 throw new SmtpException('Unable to connect via TLS.');
127:             }
128:             $this->write("EHLO $self", 250);
129:         }
130: 
131:         if ($this->username != NULL && $this->password != NULL) {
132:             $this->write('AUTH LOGIN', 334);
133:             $this->write(base64_encode($this->username), 334, 'username');
134:             $this->write(base64_encode($this->password), 235, 'password');
135:         }
136:     }
137: 
138: 
139:     /**
140:      * Disconnects from SMTP server.
141:      * @return void
142:      */
143:     private function disconnect()
144:     {
145:         fclose($this->connection);
146:         $this->connection = NULL;
147:     }
148: 
149: 
150:     /**
151:      * Writes data to server and checks response.
152:      * @param  string
153:      * @param  int   response code
154:      * @param  string  error message
155:      * @return void
156:      */
157:     private function write($line, $expectedCode = NULL, $message = NULL)
158:     {
159:         fwrite($this->connection, $line . Mail::EOL);
160:         if ($expectedCode && !in_array((int) $this->read(), (array) $expectedCode)) {
161:             throw new SmtpException('SMTP server did not accept ' . ($message ? $message : $line));
162:         }
163:     }
164: 
165: 
166:     /**
167:      * Reads response from server.
168:      * @return string
169:      */
170:     private function read()
171:     {
172:         $s = '';
173:         while (($line = fgets($this->connection, 1e3)) != NULL) { // intentionally ==
174:             $s .= $line;
175:             if (substr($line, 3, 1) === ' ') {
176:                 break;
177:             }
178:         }
179:         return $s;
180:     }
181: 
182: }
183: 
184: 
185: /**
186:  * SMTP mailer exception.
187:  *
188:  * @author     David Grudl
189:  * @package Nette\Mail
190:  */
191: class SmtpException extends Exception
192: {
193: }
194: 
Nette Framework 2.0.13 (for PHP 5.2, un-prefixed) API API documentation generated by ApiGen 2.8.0