Mail.class.php

gehe zur Dokumentation dieser Datei
00001 <?php
00002 /*
00003 OpenRat Content Management System
00004 Copyright (C) Jan Dankert
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 or 3 of the License.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 You should have received a copy of the GNU General Public License
00017 along with this program; if not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00040 class Mail
00041 {
00042      var $from    = '';
00043      var $to      = '';
00044      var $bcc     = '';
00045      var $cc      = '';
00046      var $subject = '';
00047      var $text    = '';
00048      var $header  = array();
00049      var $nl      = '';
00050      
00057      var $error = array();
00058      
00065      var $debug = true;
00066      
00067      
00076      function Mail( $to,$text,$xy='' )
00077      {
00078           global $conf;
00079           
00080           // Zeilenumbruch CR/LF gem. RFC 822.
00081           $this->nl = chr(13).chr(10);
00082           
00083           if   ( !empty($conf['mail']['from']) )
00084                $this->from = $this->header_encode($conf['mail']['from']);
00085 
00086           // Priorit�t definieren (sofern konfiguriert)
00087           if   ( !empty($conf['mail']['priority']) )
00088                $this->header[] = 'X-Priority: '.$conf['mail']['priority'];
00089                
00090           $this->header[] = 'X-Mailer: '.$this->header_encode(OR_TITLE.' '.OR_VERSION);
00091           $this->header[] = 'Content-Type: text/plain; charset='.lang( 'CHARSET' );
00092           $this->subject  = $this->header_encode(lang( 'mail_subject_'.$text ));
00093           $this->to       = $this->header_encode($to);
00094           
00095           $this->text = $this->nl.wordwrap(str_replace(';',$this->nl,lang('mail_text_'.$text)),70,$this->nl).$this->nl;
00096 
00097           // Signatur anhaengen (sofern konfiguriert)
00098           if   ( !empty($conf['mail']['signature']) )
00099           {
00100                $this->text .= $this->nl.'-- '.$this->nl;
00101                $this->text .= str_replace(';',$this->nl,$conf['mail']['signature']);
00102                $this->text .= $this->nl;
00103           }
00104           
00105           // Kopie-Empf�nger
00106           if   ( !empty($conf['mail']['cc']) )
00107                $this->cc = $this->header_encode($conf['mail']['cc']);
00108 
00109           // Blindkopie-Empf�nger
00110           if   ( !empty($conf['mail']['bcc']) )
00111                $this->bcc = $this->header_encode($conf['mail']['bcc']);
00112      }
00113 
00114 
00115 
00122      function quoted_printable_encode( $text )
00123      {
00124           $text = str_replace(' ','=20',$text);
00125           
00126           for( $i=128; $i<=255; $i++ )
00127           {
00128                $text = str_replace( chr($i),'='.dechex($i),$text );
00129           }
00130           
00131           return $text;
00132      }
00133      
00134      
00135 
00139      function setVar( $varName,$varInhalt)
00140      {
00141           $this->text = str_replace( '{'.$varName.'}', $varInhalt, $this->text );
00142      }
00143           
00144 
00151      function send()
00152      {
00153           global $conf;
00154           
00155           // Header um Adressangaben erg�nzen.
00156           if   ( !empty($this->from ) )
00157                $this->header[] = 'From: '.$this->from;
00158           
00159           if   ( !empty($this->cc ) )
00160                $this->header[] = 'Cc: '.$this->cc;
00161           
00162           if   ( !empty($this->bcc ) )
00163                $this->header[] = 'Bcc: '.$this->bcc;
00164           
00165           // Mail versenden
00166           if   ( strtolower(@$conf['mail']['client']) == 'php' )
00167           {
00168                // PHP-interne Mailfunktion verwenden.
00169                $result = @mail( $this->to,                 // Empf�nger
00170                                 $this->subject,            // Betreff
00171                                 $this->text,               // Inhalt
00172                                 // Lt. RFC822 müssen Header mit CRLF enden. 
00173                                 // ABER: Der Parameter "additional headers" verlangt offenbar \n am Zeilenende.
00174                                 implode("\n",$this->header)  );
00175                if   ( !$result )
00176                     // Die E-Mail wurde nicht akzeptiert.
00177                     // Genauer geht es leider nicht, da mail() nur einen boolean-Wert
00178                     // zur�ck liefert.
00179                     $this->error[] = 'Mail was NOT accepted by mail()';
00180                     
00181                return $result;
00182           }
00183           else
00184           {
00185                // eigenen SMTP-Dialog verwenden.
00186                $smtpConf = $conf['mail']['smtp'];
00187                
00188                if   ( !empty($smtpConf['host']))
00189                {
00190                     // Eigenen Relay-Host verwenden.
00191                     $mxHost = $smtpConf['host'];
00192                     $mxPort = intval($smtpConf['port']);
00193                }
00194                else
00195                {
00196                     // Mail direkt zustellen.
00197                     $mxHost = $this->getMxHost($this->to);
00198                     
00199                     if   ( empty($mxHost) )
00200                     {
00201                          $this->error[] = "No MX-Entry found. Mail could not be sent.";
00202                          return false;
00203                     }
00204                     
00205                     if   ($smtpConf['ssl'])
00206                          $mxPort = 465;
00207                     else
00208                          $mxPort = 25;
00209                }
00210 
00211                
00212                if   ( !empty($smtpConf['localhost']))
00213                {
00214                     $myHost = $smtpConf['localhost'];
00215                }
00216                else
00217                {
00218                     $myHost = gethostbyaddr(getenv('REMOTE_ADDR'));
00219                }
00220                
00221                if   ( $smtpConf['ssl'])
00222                     $proto = 'ssl';
00223                else
00224                     $proto = 'tcp';
00225                
00226                //connect to the host and port
00227                $smtpSocket = fsockopen($proto.'://'.$mxHost,$mxPort, $errno, $errstr, intval($smtpConf['timeout']));
00228                
00229                if   ( !is_resource($smtpSocket) )
00230                {
00231                     $this->error[] = 'Connection failed to: '.$proto.'://'.$mxHost.':'.$mxPort.' ('.$errstr.'/'.$errno.')';
00232                     return false;
00233                }
00234                
00235                $smtpResponse = fgets($smtpSocket, 4096);
00236                if   ( $this->debug)
00237                     $this->error[] = trim($smtpResponse);
00238 
00239                if   ( substr($smtpResponse,0,3) != '220' )
00240                {
00241                     $this->error[] = trim($smtpResponse);
00242                     return false;
00243                }
00244 
00245                if   ( !is_resource($smtpSocket) )
00246                {
00247                     $this->error[] = 'Connection failed to: '.$smtpConf['host'].':'.$smtpConf['port'].' ('.$smtpResponse.')';
00248                     return false;
00249                }
00250                
00251                //you have to say HELO again after TLS is started
00252                $smtpResponse = $this->sendSmtpCommand($smtpSocket,'HELO '.$myHost);
00253 
00254                if   ( substr($smtpResponse,0,3) != '250' )
00255                {
00256                     $this->error[] = "No 2xx after HELO, server says: ".$smtpResponse;
00257                     $this->sendSmtpQuit($smtpSocket);
00258                     return false;
00259                }
00260 
00261                if   ( $smtpConf['tls'] )
00262                {
00263                     $smtpResponse = $this->sendSmtpCommand($smtpSocket,'STARTTLS');
00264                     if   ( substr($smtpResponse,0,3) == '220' )
00265                     {
00266                          // STARTTLS ist gelungen.
00267                          //you have to say HELO again after TLS is started
00268                          $smtpResponse = $this->sendSmtpCommand($smtpSocket,'HELO '.$myHost);
00269           
00270                          if   ( substr($smtpResponse,0,3) != '250' )
00271                          {
00272                               $this->error[] = "No 2xx after HELO, server says: ".$smtpResponse;
00273                               $this->sendSmtpQuit($smtpSocket);
00274                               return false;
00275                          }
00276                     }
00277                     else
00278                     {
00279                          // STARTTLS ging in die Hose. Einfach weitermachen.
00280                     }
00281                }
00282    
00283                // request for auth login
00284                if   ( isset($smtpConf['auth_username']) && !empty($smtpConf['host']) && !empty($smtpConf['auth_username']))
00285                {
00286                     $smtpResponse = $this->sendSmtpCommand($smtpSocket,"AUTH LOGIN");
00287                     if   ( substr($smtpResponse,0,3) != '334' )
00288                     {
00289                          $this->error[] = "No 334 after AUTH_LOGIN, server says: ".$smtpResponse;
00290                          $this->sendSmtpQuit($smtpSocket);
00291                          return false;
00292                     }
00293      
00294                     if   ( $this->debug)
00295                          $this->error[] = 'Login for '.$smtpConf['auth_username'];
00296                          
00297                     //send the username
00298                     $smtpResponse = $this->sendSmtpCommand($smtpSocket, base64_encode($smtpConf['auth_username']));
00299                     if   ( substr($smtpResponse,0,3) != '334' )
00300                     {
00301                          $this->error[] = "No 3xx after setting username, server says: ".$smtpResponse;
00302                          $this->sendSmtpQuit($smtpSocket);
00303                          return false;
00304                     }
00305                     
00306                     //send the password
00307                     $smtpResponse = $this->sendSmtpCommand($smtpSocket, base64_encode($smtpConf['auth_password']));
00308                if   ( substr($smtpResponse,0,3) != '235' )
00309                     {
00310                          $this->error[] = "No 235 after sending password, server says: ".$smtpResponse;
00311                          $this->sendSmtpQuit($smtpSocket);
00312                          return false;
00313                     }
00314                }
00315                
00316                //email from
00317                $smtpResponse = $this->sendSmtpCommand($smtpSocket, 'MAIL FROM: <'.$conf['mail']['from'].'>');
00318           if   ( substr($smtpResponse,0,3) != '250' )
00319                {
00320                     $this->error[] = "No 2xx after MAIL_FROM, server says: ".$smtpResponse;
00321                     $this->sendSmtpQuit($smtpSocket);
00322                     return false;
00323                }
00324                
00325                //email to
00326                $smtpResponse = $this->sendSmtpCommand($smtpSocket, 'RCPT TO: <'.$this->to.'>');
00327           if   ( substr($smtpResponse,0,3) != '250' )
00328                {
00329                     $this->error[] = "No 2xx after RCPT_TO, server says: ".$smtpResponse;
00330                     $this->sendSmtpQuit($smtpSocket);
00331                     return false;
00332                }
00333                
00334                //the email
00335                $smtpResponse = $this->sendSmtpCommand($smtpSocket, "DATA");
00336                if   ( substr($smtpResponse,0,3) != '354' )
00337                {
00338                     $this->error[] = "No 354 after DATA, server says: ".$smtpResponse;
00339                     $this->sendSmtpQuit($smtpSocket);
00340                     return false;
00341                }
00342  
00343                $this->header[] = 'To: '.$this->to;
00344                $this->header[] = 'Subject: '.$this->subject;
00345                $this->header[] = 'Date: '.date('r');
00346                $this->header[] = 'Message-Id: '.'<'.getenv('REMOTE_ADDR').'.'.time().'.openrat@'.getenv('SERVER_NAME').'.'.getenv('HOSTNAME').'>';
00347          
00348                 //observe the . after the newline, it signals the end of message
00349                $smtpResponse = $this->sendSmtpCommand($smtpSocket, implode($this->nl,$this->header).$this->nl.$this->nl.$this->text.$this->nl.'.');
00350           if   ( substr($smtpResponse,0,3) != '250' )
00351                {
00352                     $this->error[] = "No 2xx after putting DATA, server says: ".$smtpResponse;
00353                     $this->sendSmtpQuit($smtpSocket);
00354                     return false;
00355                }
00356 
00357                // say goodbye
00358                $this->sendSmtpQuit($smtpSocket);
00359                return true;
00360           }
00361      }
00362      
00363      
00372      function sendSmtpCommand( $socket,$cmd )
00373      {
00374           if   ( $this->debug )
00375                $this->error[] = 'CLIENT: >>> '.trim($cmd);
00376           if   ( !is_resource($socket) )
00377           {
00378                // Die Verbindung ist geschlossen. Dies kann bei dieser
00379                // Implementierung eigentlich nur dann passieren, wenn
00380                // der Server die Verbindung schlie�t.
00381                // Dieser Client trennt die Verbindung nur nach einem "QUIT".
00382                $this->error[] = "Connection lost";
00383                return;
00384           }
00385           
00386           fputs($socket,$cmd.$this->nl);
00387           $response = trim(fgets($socket, 4096));
00388           if   ( $this->debug )
00389                $this->error[] = 'SERVER: <<< '.$response;
00390           return $response;
00391      }
00392      
00393      
00394      
00401      function sendSmtpQuit( $socket )
00402      {
00403           
00404           if   ( $this->debug )
00405                $this->error[] = "CLIENT: >>> QUIT";
00406           if   ( !is_resource($socket) )
00407                return;
00408                // Wenn die Verbindung nicht mehr da ist, brauchen wir
00409                // auch kein QUIT mehr :)
00410 
00411           
00412           fputs($socket,'QUIT'.$this->nl);
00413           $response = trim(fgets($socket, 4096));
00414           if   ( $this->debug )
00415                $this->error[] = 'SERVER: <<< '.$response;
00416                
00417           if   ( substr($response,0,3) != '221' )
00418                $this->error[] = 'QUIT FAILED: '.$response;
00419                
00420           fclose($socket);
00421      }
00422      
00423      
00424      
00432      function header_encode( $text )
00433      {
00434           global $conf;
00435           
00436           if   ( empty($conf['mail']['header_encoding']) )
00437                return $text;
00438 
00439           $woerter = explode(' ',$text);
00440           $neu = array();
00441 
00442           
00443           foreach( $woerter as $wort )
00444           {
00445                $type     = strtolower(substr($conf['mail']['header_encoding'],0,1));
00446                $neu_wort = '';
00447                
00448                if   ( $type == 'b' )
00449                     $neu_wort = base64_encode($wort);
00450                elseif    ( $type == 'q' )
00451                     $neu_wort = $this->quoted_printable_encode($wort);
00452                else
00453                     Logger::error( 'Mail-Configuratin broken: UNKNOWN Header-Encoding type: '.$type);
00454 
00455                if   ( strlen($wort)==strlen($neu_wort) )
00456                     $neu[] = $wort;
00457                else
00458                     $neu[] = '=?'.lang('CHARSET').'?'.$type.'?'.$neu_wort.'?=';
00459           }
00460           
00461           return implode(' ',$neu);
00462      }
00463      
00464 
00472      function getMxHost( $to )
00473      {
00474           list($user,$host) = explode('@',$to.'@');
00475           
00476           if   ( empty($host) )
00477           {
00478                $this->error[] = 'Illegal mail address - No hostname found.';
00479                return "";
00480           }
00481                
00482           list($host) = explode('>',$host);
00483                     
00484           $mxHostsName = array();
00485           $mxHostsPrio = array();
00486           getmxrr($host,$mxHostsName,$mxHostsPrio);
00487           
00488           $mxList = array();
00489           foreach( $mxHostsName as $id=>$mxHostName )
00490           {
00491                $mxList[$mxHostName] = $mxHostsPrio[$id]; 
00492           }
00493           asort($mxList);
00494           return key($mxList);
00495      }
00496 }
00497 
00498 
00499 ?>

Erzeugt am Thu May 14 00:55:49 2009 für OpenRat von  doxygen 1.5.8