Overview

Namespaces

  • Jyxo
    • Beholder
      • TestCase
    • Gettext
      • Parser
    • Input
      • Chain
      • Filter
      • Validator
    • Mail
      • Email
        • Attachment
      • Parser
      • Sender
    • Rpc
      • Json
      • Xml
    • Shell
    • Spl
    • Svn
    • Time
    • Webdav
  • PHP

Classes

  • Result
  • Smtp

Exceptions

  • CreateException
  • Exception
  • RecipientUnknownException
  • SmtpException
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  1: <?php
  2: 
  3: /**
  4:  * Jyxo PHP Library
  5:  *
  6:  * LICENSE
  7:  *
  8:  * This source file is subject to the new BSD license that is bundled
  9:  * with this package in the file license.txt.
 10:  * It is also available through the world-wide-web at this URL:
 11:  * https://github.com/jyxo/php/blob/master/license.txt
 12:  */
 13: 
 14: namespace Jyxo\Mail\Sender;
 15: 
 16: /**
 17:  * Class for sending emails using a SMTP server.
 18:  * Works in combination with \Jyxo\Mail\Sender.
 19:  *
 20:  * @category Jyxo
 21:  * @package Jyxo\Mail
 22:  * @subpackage Sender
 23:  * @copyright Copyright (c) 2005-2011 Jyxo, s.r.o.
 24:  * @license https://github.com/jyxo/php/blob/master/license.txt
 25:  * @author Jaroslav HanslĂ­k
 26:  */
 27: class Smtp
 28: {
 29:     /**
 30:      * Line endings.
 31:      *
 32:      * @var string
 33:      */
 34:     const LINE_END = "\r\n";
 35: 
 36:     /**
 37:      * Established connection.
 38:      *
 39:      * @var resource
 40:      */
 41:     private $connection = null;
 42: 
 43:     /**
 44:      * SMTP server.
 45:      *
 46:      * @var string
 47:      */
 48:     private $host = 'localhost';
 49: 
 50:     /**
 51:      * SMTP port.
 52:      *
 53:      * @var integer
 54:      */
 55:     private $port = 25;
 56: 
 57:     /**
 58:      * SMTP HELO value.
 59:      *
 60:      * @var string
 61:      */
 62:     private $helo = 'localhost';
 63: 
 64:     /**
 65:      * SMTP connection timeout.
 66:      *
 67:      * @var string
 68:      */
 69:     private $timeout = 5;
 70: 
 71:     /**
 72:      * Creates an instance.
 73:      *
 74:      * @param string $host Server hostname
 75:      * @param integer $port Server port
 76:      * @param string $helo HELO value
 77:      * @param integer $timeout Connection timeout
 78:      */
 79:     public function __construct($host = 'localhost', $port = 25, $helo = 'localhost', $timeout = 5)
 80:     {
 81:         $this->host = (string) $host;
 82:         $this->port = (int) $port;
 83:         $this->timeout = (int) $timeout;
 84:         $this->helo = (string) $helo;
 85:     }
 86: 
 87:     /**
 88:      * Destroys an instance and disconnects from the server.
 89:      */
 90:     public function __destruct()
 91:     {
 92:         if (is_resource($this->connection)) {
 93:             $this->disconnect();
 94:         }
 95:     }
 96: 
 97:     /**
 98:      * Connects to the SMTP server.
 99:      *
100:      * @return \Jyxo\Mail\Sender\Smtp
101:      * @throws \Jyxo\Mail\Sender\SmtpException If a connection error occurs
102:      */
103:     public function connect()
104:     {
105:         $this->connection = fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout);
106:         if (false === $this->connection) {
107:             throw new SmtpException('CONNECTION: ' . $errno . ' ' . $errstr);
108:         }
109: 
110:         // Reads the initial connection data
111:         $this->readData();
112: 
113:         // Sends EHLO/HELO
114:         $this->commandHelo();
115: 
116:         return $this;
117:     }
118: 
119:     /**
120:      * Disconnects from server.
121:      *
122:      * @return \Jyxo\Mail\Sender\Smtp
123:      */
124:     public function disconnect()
125:     {
126:         if (is_resource($this->connection)) {
127:             try {
128:                 $this->reset();
129:                 $this->writeData('QUIT');
130:                 fclose($this->connection);
131:                 $this->connection = null;
132:             } catch (\Exception $e) {
133:                 // Disconnecting; ignore possible exceptions
134:             }
135:         }
136: 
137:         return $this;
138:     }
139: 
140:     /**
141:      * Connects to the server using a username and password.
142:      *
143:      * @param string $user Username
144:      * @param string $password Password
145:      * @return \Jyxo\Mail\Sender\Smtp
146:      * @throws \Jyxo\Mail\Sender\SmtpException On authentication error
147:      */
148:     public function auth($user, $password)
149:     {
150:         $this->writeData('AUTH LOGIN');
151:         $response = $this->readData();
152:         if ('334' !== substr($response, 0, 3)) {
153:             throw new SmtpException('AUTH: ' . $response);
154:         }
155:         $this->writeData(base64_encode($user));
156:         $response = $this->readData();
157:         if ('334' !== substr($response, 0, 3)) {
158:             throw new SmtpException('AUTH: ' . $response);
159:         }
160:         $this->writeData(base64_encode($password));
161:         $response = $this->readData();
162:         if ('235' !== substr($response, 0, 3)) {
163:             throw new SmtpException('AUTH: ' . $response);
164:         }
165: 
166:         return $this;
167:     }
168: 
169:     /**
170:      * Sets the sender.
171:      *
172:      * @param string $from Sender
173:      * @return \Jyxo\Mail\Sender\Smtp
174:      */
175:     public function from($from)
176:     {
177:         $this->commandMailFrom($from);
178: 
179:         return $this;
180:     }
181: 
182:     /**
183:      * Adds a recipient.
184:      *
185:      * @param string $recipient Recipient
186:      * @return \Jyxo\Mail\Sender\Smtp
187:      */
188:     public function recipient($recipient)
189:     {
190:         $this->commandRcptTo($recipient);
191: 
192:         return $this;
193:     }
194: 
195:     /**
196:      * Sends email headers and body.
197:      *
198:      * @param string $header Headers
199:      * @param string $body Body
200:      * @return \Jyxo\Mail\Sender\Smtp
201:      * @throws \Jyxo\Mail\Sender\SmtpException On data sending error
202:      */
203:     public function data($header, $body)
204:     {
205:         $lineEnds = array(\Jyxo\Mail\Sender::LINE_END . '.' => self::LINE_END . '..', \Jyxo\Mail\Sender::LINE_END => self::LINE_END);
206:         $header = strtr($header, $lineEnds);
207:         $body = strtr($body, $lineEnds);
208:         if ('.' == $body[0]) {
209:             $body = '.' . $body;
210:         }
211: 
212:         $this->commandData();
213:         $this->writeData(trim($header));
214:         $this->writeData('');
215:         $this->writeData($body);
216:         $this->writeData('.');
217: 
218:         $response = $this->readData();
219:         if ('250' !== substr($response, 0, 3)) {
220:             throw new SmtpException('SEND: ' . $response);
221:         }
222: 
223:         return $this;
224:     }
225: 
226:     /**
227:      * Resets previous commands.
228:      *
229:      * @return \Jyxo\Mail\Sender\Smtp
230:      */
231:     public function reset()
232:     {
233:         $this->commandRset();
234: 
235:         return $this;
236:     }
237: 
238:     /**
239:      * Sends the EHLO/HELO command.
240:      *
241:      * @throws \Jyxo\Mail\Sender\SmtpException On error
242:      */
243:     private function commandHelo()
244:     {
245:         $this->writeData('EHLO ' . $this->helo);
246:         $response = $this->readData();
247:         if ('250' !== substr($response, 0, 3)) {
248:             $this->writeData('HELO ' . $this->helo);
249:             $response = $this->readData();
250:             if ('250' !== substr($response, 0, 3)) {
251:                 throw new SmtpException('HELO: ' . $response);
252:             }
253:         }
254:     }
255: 
256:     /**
257:      * Sends the MAIL FROM command.
258:      *
259:      * @param string $from
260:      * @throws \Jyxo\Mail\Sender\SmtpException On error
261:      */
262:     private function commandMailFrom($from)
263:     {
264:         $this->writeData('MAIL FROM: <' . $from . '>');
265:         $response = $this->readData();
266:         if ('250' !== substr($response, 0, 3)) {
267:             throw new SmtpException('MAIL FROM: ' . $response);
268:         }
269:     }
270: 
271:     /**
272:      * Sends the RCPT TO command.
273:      *
274:      * @param string $recipient
275:      * @throws \Jyxo\Mail\Sender\SmtpException On error
276:      */
277:     private function commandRcptTo($recipient)
278:     {
279:         $this->writeData('RCPT TO: <' . $recipient . '>');
280:         $response = $this->readData();
281:         if ('250' !== substr($response, 0, 3)) {
282:             throw new SmtpException('RCPT TO: ' . $response);
283:         }
284:     }
285: 
286:     /**
287:      * Sends the DATA command.
288:      *
289:      * @throws \Jyxo\Mail\Sender\SmtpException On error
290:      */
291:     private function commandData()
292:     {
293:         $this->writeData('DATA');
294:         $response = $this->readData();
295:         if ('354' !== substr($response, 0, 3)) {
296:             throw new SmtpException('DATA: ' . $response);
297:         }
298:     }
299: 
300:     /**
301:      * Sends the RSET command.
302:      *
303:      * @throws \Jyxo\Mail\Sender\SmtpException On error
304:      */
305:     private function commandRset()
306:     {
307:         $this->writeData('RSET');
308:         $response = $this->readData();
309:         if ('250' !== substr($response, 0, 3)) {
310:             throw new SmtpException('RSET: ' . $response);
311:         }
312:     }
313: 
314:     /**
315:      * Reads data from the server.
316:      *
317:      * @return string
318:      */
319:     private function readData()
320:     {
321:         $data = '';
322:         $i = 0;
323:         while ($line = fgets($this->connection)) {
324:             $data .= $line;
325:             if (' ' == substr($line, 3, 1)) {
326:                 break;
327:             }
328:         }
329:         return $data;
330:     }
331: 
332:     /**
333:      * Sends data to the server.
334:      *
335:      * @param string $data Data
336:      * @throws \Jyxo\Mail\Sender\SmtpException On error
337:      */
338:     private function writeData($data)
339:     {
340:         if (!fwrite($this->connection, $data . self::LINE_END)) {
341:             throw new SmtpException('Error while writing data.');
342:         }
343:     }
344: }
345: 
Jyxo PHP Library API documentation generated by ApiGen 2.3.0