eZ Publish  [4.0]
ezsmtp.php
Go to the documentation of this file.
00001 <?php
00002 /***************************************
00003 ** Filename.......: class.smtp.inc
00004 ** Project........: SMTP Class
00005 ** Version........: 1.0.5
00006 ** Last Modified..: 21 December 2001
00007 ***************************************/
00008 
00009     class smtp
00010     {
00011         const STATUS_NOT_CONNECTED = 1;
00012         const STATUS_CONNECTED = 2;
00013         const CRLF = "\r\n";
00014 
00015         public $authenticated;
00016         public $connection;
00017         public $recipients;
00018         public $CcRecipients;
00019         public $BccRecipients;
00020         public $headers;
00021         public $timeout;
00022         public $errors;
00023         public $status;
00024         public $body;
00025         public $from;
00026         public $host;
00027         public $port;
00028         public $helo;
00029         public $auth;
00030         public $user;
00031         public $pass;
00032 
00033         /***************************************
00034         ** Constructor function. Arguments:
00035         ** $params - An assoc array of parameters:
00036         **
00037         **   host    - The hostname of the smtp server        Default: localhost
00038         **   port    - The port the smtp server runs on        Default: 25
00039         **   helo    - What to send as the HELO command        Default: localhost
00040         **             (typically the hostname of the
00041         **             machine this script runs on)
00042         **   auth    - Whether to use basic authentication    Default: FALSE
00043         **   user    - Username for authentication            Default: <blank>
00044         **   pass    - Password for authentication            Default: <blank>
00045         **   timeout - The timeout in seconds for the call    Default: 5
00046         **             to fsockopen()
00047         ***************************************/
00048 
00049         function smtp( $params = array() )
00050         {
00051             $this->authenticated = FALSE;
00052             $this->timeout       = 5;
00053             $this->status        = smtp::STATUS_NOT_CONNECTED;
00054             $this->host          = 'localhost';
00055             $this->port          = 25;
00056             $this->helo          = 'localhost';
00057             $this->auth          = FALSE;
00058             $this->user          = '';
00059             $this->pass          = '';
00060             $this->errors        = array();
00061 
00062             foreach ( $params as $key => $value )
00063             {
00064                 $this->$key = $value;
00065             }
00066         }
00067 
00068         /***************************************
00069         ** Connect function.
00070         ** It will connect to the server and send
00071         ** the HELO command.
00072         ***************************************/
00073 
00074         function connect($params = array())
00075         {
00076             $this->connection = fsockopen( $this->host, $this->port, $errno, $errstr, $this->timeout );
00077             if ( function_exists( 'socket_set_timeout' ) )
00078             {
00079                 @socket_set_timeout( $this->connection, 5, 0 );
00080             }
00081 
00082             $greeting = $this->get_data();
00083             if ( is_resource( $this->connection ) )
00084             {
00085                 $result = $this->auth ? $this->ehlo() : $this->helo();
00086                 if ( $result )
00087                 {
00088                     $this->status = smtp::STATUS_CONNECTED;
00089                 }
00090                 return $result;
00091             }
00092             else
00093             {
00094                 $this->errors[] = 'Failed to connect to server: ' . $errstr;
00095                 return FALSE;
00096             }
00097         }
00098 
00099         /***************************************
00100         ** Function which handles sending the mail.
00101         ** Arguments:
00102         ** $params    - Optional assoc array of parameters.
00103         **            Can contain:
00104         **              recipients - Indexed array of recipients
00105         **              from       - The from address. (used in MAIL FROM:),
00106         **                           this will be the return path
00107         **              headers    - Indexed array of headers, one header per array entry
00108         **              body       - The body of the email
00109         **            It can also contain any of the parameters from the connect()
00110         **            function
00111         ***************************************/
00112 
00113         function send( $params = array() )
00114         {
00115             foreach ( $params as $key => $value )
00116             {
00117                 $this->set( $key, $value );
00118             }
00119 
00120             if ( $this->is_connected() )
00121             {
00122                 // Do we auth or not? Note the distinction between the auth variable and auth() function
00123                 if ( $this->auth AND !$this->authenticated )
00124                 {
00125                     if ( !$this->auth() )
00126                         return FALSE;
00127                 }
00128                 $this->mail( $this->from );
00129                 if ( is_array( $this->recipients ) )
00130                     foreach ( $this->recipients as $value )
00131                         $this->rcpt( $value );
00132                 else
00133                     $this->rcpt( $this->recipients );
00134 
00135                 if ( is_array( $this->CcRecipients ) )
00136                     foreach( $this->CcRecipients as $value )
00137                         $this->rcpt( $value );
00138                 else
00139                     $this->rcpt( $this->CcRecipients );
00140 
00141                 if ( is_array( $this->BccRecipients ) )
00142                     foreach ( $this->BccRecipients as $value )
00143                         $this->rcpt( $value );
00144                 else
00145                     $this->rcpt( $this->BccRecipients );
00146 
00147                 if ( !$this->data() )
00148                     return FALSE;
00149 
00150                 // Transparency
00151                 $headers = str_replace( smtp::CRLF.'.', smtp::CRLF.'..', trim( implode( smtp::CRLF, $this->headers ) ) );
00152                 $body    = str_replace( smtp::CRLF.'.', smtp::CRLF.'..', $this->body );
00153                 $body    = $body[0] == '.' ? '.'.$body : $body;
00154 
00155                 $this->send_data( $headers );
00156                 $this->send_data( '' );
00157                 $this->send_data( $body );
00158                 $this->send_data( '.' );
00159 
00160                 $result = ( substr( trim( $this->get_data() ), 0, 3) === '250' );
00161                 return $result;
00162             }
00163             else
00164             {
00165                 $this->errors[] = 'Not connected!';
00166                 return FALSE;
00167             }
00168         }
00169 
00170         /***************************************
00171         ** Function to implement HELO cmd
00172         ***************************************/
00173 
00174         function helo()
00175         {
00176             return( $this->send_cmd( 'HELO ' . $this->helo, '250' ) );
00177         }
00178 
00179 
00180         /***************************************
00181         ** Function to implement EHLO cmd
00182         ***************************************/
00183 
00184         function ehlo()
00185         {
00186             /* return the result of the EHLO command */
00187             return ( $this->send_cmd( 'EHLO ' . $this->helo, '250' ) );
00188         }
00189 
00190         /***************************************
00191         ** Function to implement RSET cmd
00192         ***************************************/
00193 
00194         function rset()
00195         {
00196             /* return the result of the RSET command */
00197             return ( $this->send_cmd( 'RSET', '250' ) );
00198         }
00199 
00200         /***************************************
00201         ** Function to implement QUIT cmd
00202         ***************************************/
00203 
00204         function quit()
00205         {
00206             /* if QUIT OK */
00207             if ( $this->send_cmd( 'QUIT', '221' ) )
00208             {
00209                 /* unset the connection flag and return TRUE */
00210                 $this->status = smtp::STATUS_NOT_CONNECTED;
00211                 return TRUE;
00212             }
00213             /* in other case return FALSE */
00214             return FALSE;
00215         }
00216 
00217         /***************************************
00218         ** Function to implement AUTH cmd
00219         ***************************************/
00220 
00221         function auth()
00222         {
00223             /* if the connection is made */
00224             if ( $this->send_cmd('AUTH LOGIN', '334' ) )
00225             {
00226                 /* if sending username ok */
00227                 if ( $this->send_cmd( base64_encode( $this->user ), '334' ) )
00228                 {
00229                     /* if sending password ok */
00230                     if ( $this->send_cmd( base64_encode( $this->pass ), '235' ) )
00231                     {
00232                         /* set the authenticated  flag and return TRUE */
00233                         $this->authenticated = TRUE;
00234                          return TRUE;
00235                     }
00236                 }
00237             }
00238             /* in other case return FALSE */
00239             return FALSE;
00240         }
00241 
00242         /***************************************
00243         ** Function that handles the MAIL FROM: cmd
00244         ***************************************/
00245 
00246         function mail( $from )
00247         {
00248             /* normalize the from field */
00249             if ( !preg_match( "/<.+>/", $from ) )
00250                 $from = '<' . $from .'>';
00251 
00252             /* return the result of the MAIL FROM command */
00253             return ( $this->send_cmd('MAIL FROM:' . $from . '', '250' ) );
00254         }
00255 
00256         /***************************************
00257         ** Function that handles the RCPT TO: cmd
00258         ***************************************/
00259 
00260         function rcpt( $to )
00261         {
00262             /* normalize the to field */
00263             if ( !preg_match( "/<.+>/", $to ) )
00264                 $to = '<' . $to .'>';
00265 
00266             /* return the result of the RCPT TO command */
00267             return ( $this->send_cmd( 'RCPT TO:' . $to . '', '250' ) );
00268         }
00269 
00270 
00271         /***************************************
00272         ** Function that sends the DATA cmd
00273         ***************************************/
00274 
00275         function data()
00276         {
00277             /* return the result of the RCPT TO command */
00278             return ( $this->send_cmd('DATA', '354' ) );
00279         }
00280 
00281         /***************************************
00282         ** Function to determine if this object
00283         ** is connected to the server or not.
00284         ***************************************/
00285 
00286         function is_connected()
00287         {
00288             return ( is_resource( $this->connection ) AND ( $this->status === smtp::STATUS_CONNECTED ) );
00289         }
00290 
00291         /***************************************
00292         ** Function to send a bit of data
00293         ***************************************/
00294 
00295         function send_data( $data )
00296         {
00297             if ( is_resource( $this->connection ) )
00298             {
00299                 return fwrite( $this->connection, $data.smtp::CRLF, strlen( $data ) + 2 );
00300             }
00301             else
00302                 return FALSE;
00303         }
00304 
00305         /***************************************
00306         ** Function to get data.
00307         ***************************************/
00308 
00309         function get_data()
00310         {
00311             $return = '';
00312             $line   = '';
00313             $loops  = 0;
00314 
00315             if ( is_resource( $this->connection ) )
00316             {
00317                 while ( ( strpos( $return, smtp::CRLF ) === FALSE OR substr( $line, 3, 1 ) !== ' ' ) AND $loops < 100 )
00318                 {
00319                     $line    = fgets( $this->connection, 512 );
00320                     $return .= $line;
00321                     $loops++;
00322                 }
00323                 return $return;
00324             }
00325             else
00326                 return FALSE;
00327         }
00328 
00329         /***************************************
00330         ** Sets a variable
00331         ***************************************/
00332 
00333         function set( $var, $value )
00334         {
00335             $this->$var = $value;
00336             return TRUE;
00337         }
00338 
00339         /********************************************************
00340         ** Function to simply send a command to the smtp socket
00341         *********************************************************/
00342         function send_cmd( $msg, $answer )
00343         {
00344             /* if the connection is made */
00345             if ( $error = is_resource( $this->connection ) )
00346             {
00347                 /* if sending DATA ok */
00348                 if ( $error = $this->send_data( $msg ) )
00349                 {
00350                     /* Wait for server answer */
00351                     $error = $this->get_data();
00352 
00353                     /* return TRUE if the server answered the expected tag */
00354                     if( substr( trim( $error ), 0, 3 ) === $answer )
00355                     {
00356                         return TRUE;
00357                     }
00358                 }
00359             }
00360             /* else return FALSE and set an error */
00361             $this->errors[] = $msg . ' command failed, output: ' . $error;
00362             return FALSE;
00363         }
00364 
00365     } // End of class
00366 ?>