Namespaces

  • 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

  • Message
  • MimePart
  • SendmailMailer
  • SmtpMailer

Interfaces

  • IMailer

Exceptions

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