00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009 define('SMTP_STATUS_NOT_CONNECTED', 1, TRUE);
00010 define('SMTP_STATUS_CONNECTED', 2, TRUE);
00011
00012 class smtp
00013 {
00014
00015 var $authenticated;
00016 var $connection;
00017 var $recipients;
00018 var $CcRecipients;
00019 var $BccRecipients;
00020 var $headers;
00021 var $timeout;
00022 var $errors;
00023 var $status;
00024 var $body;
00025 var $from;
00026 var $host;
00027 var $port;
00028 var $helo;
00029 var $auth;
00030 var $user;
00031 var $pass;
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 function smtp( $params = array() )
00050 {
00051 if( !defined( 'CRLF' ) )
00052 define( 'CRLF', "\r\n", TRUE );
00053
00054 $this->authenticated = FALSE;
00055 $this->timeout = 5;
00056 $this->status = SMTP_STATUS_NOT_CONNECTED;
00057 $this->host = 'localhost';
00058 $this->port = 25;
00059 $this->helo = 'localhost';
00060 $this->auth = FALSE;
00061 $this->user = '';
00062 $this->pass = '';
00063 $this->errors = array();
00064
00065 foreach ( $params as $key => $value )
00066 {
00067 $this->$key = $value;
00068 }
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 function connect($params = array())
00081 {
00082 if ( !isset( $this->status ) )
00083 {
00084 $obj = new smtp( $params );
00085 if( $obj->connect() )
00086 {
00087 $obj->status = SMTP_STATUS_CONNECTED;
00088 }
00089 return $obj;
00090 }
00091 else
00092 {
00093 $this->connection = fsockopen( $this->host, $this->port, $errno, $errstr, $this->timeout );
00094 if ( function_exists( 'socket_set_timeout' ) )
00095 {
00096 @socket_set_timeout( $this->connection, 5, 0 );
00097 }
00098
00099 $greeting = $this->get_data();
00100 if ( is_resource( $this->connection ) )
00101 {
00102 return $this->auth ? $this->ehlo() : $this->helo();
00103 }
00104 else
00105 {
00106 $this->errors[] = 'Failed to connect to server: ' . $errstr;
00107 return FALSE;
00108 }
00109 }
00110 }
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 function send( $params = array() )
00127 {
00128 foreach ( $params as $key => $value )
00129 {
00130 $this->set( $key, $value );
00131 }
00132
00133 if ( $this->is_connected() )
00134 {
00135
00136 if ( $this->auth AND !$this->authenticated )
00137 {
00138 if ( !$this->auth() )
00139 return FALSE;
00140 }
00141 $this->mail( $this->from );
00142 if ( is_array( $this->recipients ) )
00143 foreach ( $this->recipients as $value )
00144 $this->rcpt( $value );
00145 else
00146 $this->rcpt( $this->recipients );
00147
00148 if ( is_array( $this->CcRecipients ) )
00149 foreach( $this->CcRecipients as $value )
00150 $this->rcpt( $value );
00151 else
00152 $this->rcpt( $this->CcRecipients );
00153
00154 if ( is_array( $this->BccRecipients ) )
00155 foreach ( $this->BccRecipients as $value )
00156 $this->rcpt( $value );
00157 else
00158 $this->rcpt( $this->BccRecipients );
00159
00160 if ( !$this->data() )
00161 return FALSE;
00162
00163
00164 $headers = str_replace( CRLF.'.', CRLF.'..', trim( implode( CRLF, $this->headers ) ) );
00165 $body = str_replace( CRLF.'.', CRLF.'..', $this->body );
00166 $body = $body[0] == '.' ? '.'.$body : $body;
00167
00168 $this->send_data( $headers );
00169 $this->send_data( '' );
00170 $this->send_data( $body );
00171 $this->send_data( '.' );
00172
00173 $result = ( substr( trim( $this->get_data() ), 0, 3) === '250' );
00174 return $result;
00175 }
00176 else
00177 {
00178 $this->errors[] = 'Not connected!';
00179 return FALSE;
00180 }
00181 }
00182
00183
00184
00185
00186
00187 function helo()
00188 {
00189 return( $this->send_cmd( 'HELO ' . $this->helo, '250' ) );
00190 }
00191
00192
00193
00194
00195
00196
00197 function ehlo()
00198 {
00199
00200 return ( $this->send_cmd( 'EHLO ' . $this->helo, '250' ) );
00201 }
00202
00203
00204
00205
00206
00207 function rset()
00208 {
00209
00210 return ( $this->send_cmd( 'RSET', '250' ) );
00211 }
00212
00213
00214
00215
00216
00217 function quit()
00218 {
00219
00220 if ( $this->send_cmd( 'QUIT', '221' ) )
00221 {
00222
00223 $this->status = SMTP_STATUS_NOT_CONNECTED;
00224 return TRUE;
00225 }
00226
00227 return FALSE;
00228 }
00229
00230
00231
00232
00233
00234 function auth()
00235 {
00236
00237 if ( $this->send_cmd('AUTH LOGIN', '334' ) )
00238 {
00239
00240 if ( $this->send_cmd( base64_encode( $this->user ), '334' ) )
00241 {
00242
00243 if ( $this->send_cmd( base64_encode( $this->pass ), '235' ) )
00244 {
00245
00246 $this->authenticated = TRUE;
00247 return TRUE;
00248 }
00249 }
00250 }
00251
00252 return FALSE;
00253 }
00254
00255
00256
00257
00258
00259 function mail( $from )
00260 {
00261
00262 if ( !preg_match( "/<.+>/", $from ) )
00263 $from = '<' . $from .'>';
00264
00265
00266 return ( $this->send_cmd('MAIL FROM:' . $from . '', '250' ) );
00267 }
00268
00269
00270
00271
00272
00273 function rcpt( $to )
00274 {
00275
00276 if ( !preg_match( "/<.+>/", $to ) )
00277 $to = '<' . $to .'>';
00278
00279
00280 return ( $this->send_cmd( 'RCPT TO:' . $to . '', '250' ) );
00281 }
00282
00283
00284
00285
00286
00287
00288 function data()
00289 {
00290
00291 return ( $this->send_cmd('DATA', '354' ) );
00292 }
00293
00294
00295
00296
00297
00298
00299 function is_connected()
00300 {
00301 return ( is_resource( $this->connection ) AND ( $this->status === SMTP_STATUS_CONNECTED ) );
00302 }
00303
00304
00305
00306
00307
00308 function send_data( $data )
00309 {
00310 if ( is_resource( $this->connection ) )
00311 {
00312 return fwrite( $this->connection, $data.CRLF, strlen( $data ) + 2 );
00313 }
00314 else
00315 return FALSE;
00316 }
00317
00318
00319
00320
00321
00322 function get_data()
00323 {
00324 $return = '';
00325 $line = '';
00326 $loops = 0;
00327
00328 if ( is_resource( $this->connection ) )
00329 {
00330 while ( ( strpos( $return, CRLF ) === FALSE OR substr( $line, 3, 1 ) !== ' ' ) AND $loops < 100 )
00331 {
00332 $line = fgets( $this->connection, 512 );
00333 $return .= $line;
00334 $loops++;
00335 }
00336 return $return;
00337 }
00338 else
00339 return FALSE;
00340 }
00341
00342
00343
00344
00345
00346 function set( $var, $value )
00347 {
00348 $this->$var = $value;
00349 return TRUE;
00350 }
00351
00352
00353
00354
00355 function send_cmd( $msg, $answer )
00356 {
00357
00358 if ( $error = is_resource( $this->connection ) )
00359 {
00360
00361 if ( $error = $this->send_data( $msg ) )
00362 {
00363
00364 $error = $this->get_data();
00365
00366
00367 if( substr( trim( $error ), 0, 3 ) === $answer )
00368 {
00369 return TRUE;
00370 }
00371 }
00372 }
00373
00374 $this->errors[] = $msg . ' command failed, output: ' . $error;
00375 return FALSE;
00376 }
00377
00378 }
00379 ?>