Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00087 class t3lib_readmail { 00088 var $dateAbbrevs = array( 00089 'JAN' => 1, 00090 'FEB' => 2, 00091 'MAR' => 3, 00092 'APR' => 4, 00093 'MAY' => 5, 00094 'JUN' => 6, 00095 'JUL' => 7, 00096 'AUG' => 8, 00097 'SEP' => 9, 00098 'OCT' => 10, 00099 'NOV' => 11, 00100 'DEC' => 12 00101 ); 00102 var $serverGMToffsetMinutes = 60; // = +0100 (CET) 00103 00104 00105 00106 00107 00108 00109 /******************************* 00110 * 00111 * FUNCTIONS for the Dmailer 00112 * 00113 ********************************/ 00114 00122 function find_MIDfromReturnPath($to) { 00123 $parts = explode('mid',strtolower($to)); 00124 $moreParts=explode('_',$parts[1]); 00125 $out=array( 00126 'mid' => $moreParts[0], 00127 'rtbl' => substr($moreParts[1],0,1), 00128 'rid' => intval(substr($moreParts[1],1)) 00129 ); 00130 if ($out['rtbl']=='p') $out['rtbl']='P'; 00131 00132 return($out); 00133 } 00134 00142 function find_XTypo3MID($content) { 00143 if (strstr($content,'X-Typo3MID:')) { 00144 $p=explode('X-Typo3MID:',$content,2); 00145 $l=explode(chr(10),$p[1],2); 00146 list($mid,$hash)=t3lib_div::trimExplode('-',$l[0]); 00147 if (md5($mid)==$hash) { 00148 $moreParts=explode('_',substr($mid,3)); 00149 $out=array( 00150 'mid' => $moreParts[0], 00151 'rtbl' => substr($moreParts[1],0,1), 00152 'rid' => substr($moreParts[1],1) 00153 ); 00154 return($out); 00155 } 00156 } 00157 } 00158 00159 00160 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 00171 00172 00173 00174 00175 /******************************* 00176 * 00177 * General 00178 * 00179 ********************************/ 00180 00188 function getMessage($mailParts) { 00189 if ($mailParts['content-type']) { 00190 $CType = $this->getCType($mailParts['content-type']); 00191 if ($CType['boundary']) { 00192 $parts = $this->getMailBoundaryParts($CType['boundary'],$mailParts['CONTENT']); 00193 $c=$this->getTextContent($parts[0]); 00194 } else { 00195 $c=$this->getTextContent( 00196 'Content-Type: '.$mailParts['content-type'].' 00197 '.$mailParts['CONTENT'] 00198 ); 00199 } 00200 } else { 00201 $c = $mailParts['CONTENT']; 00202 } 00203 return $c; 00204 } 00205 00213 function getTextContent($content) { 00214 $p=$this->extractMailHeader($content); 00215 // Here some decoding might be needed... 00216 // However we just return what is believed to be the proper notification: 00217 return $p['CONTENT']; 00218 } 00219 00228 function getMailBoundaryParts($boundary,$content) { 00229 $mParts = explode('--'.$boundary,$content); 00230 unset($mParts[0]); 00231 reset($mParts); 00232 $new=array(); 00233 while(list(,$val)=each($mParts)) { 00234 if (trim($val)=='--') break; 00235 $new[] = ltrim($val); 00236 } 00237 return $new; 00238 } 00239 00248 function getCType($str) { 00249 $parts = explode(';',$str); 00250 $cTypes=array(); 00251 $cTypes['ContentType']=$parts[0]; 00252 next($parts); 00253 while(list(,$ppstr)=each($parts)) { 00254 $mparts = explode('=',$ppstr,2); 00255 if (count($mparts)>1) { 00256 $cTypes[strtolower(trim($mparts[0]))]=ereg_replace('^"','',trim(ereg_replace('"$','',trim($mparts[1])))); 00257 } else { 00258 $cTypes[]=$ppstr; 00259 } 00260 } 00261 return $cTypes; 00262 } 00263 00271 function analyseReturnError($c) { 00272 $cp=array(); 00273 if (strstr($c,'--- Below this line is a copy of the message.')) { // QMAIL 00274 list($c)=explode('--- Below this line is a copy of the message.',$c); // Splits by the QMAIL divider 00275 $cp['content']=trim($c); 00276 $parts = explode('>:',$c,2); 00277 $cp['reason_text']=trim($parts[1]); 00278 $cp['mailserver']='Qmail'; 00279 if (eregi('550|no mailbox|account does not exist',$cp['reason_text'])) { 00280 $cp['reason']=550; // 550 Invalid recipient 00281 } elseif (stristr($cp['reason_text'],'couldn\'t find any host named')) { 00282 $cp['reason']=2; // Bad host 00283 } elseif (eregi('Error in Header|invalid Message-ID header',$cp['reason_text'])) { 00284 $cp['reason']=554; 00285 } else { 00286 $cp['reason']=-1; 00287 } 00288 } elseif (strstr($c,'The Postfix program')) { // Postfix 00289 $cp['content']=trim($c); 00290 $parts = explode('>:',$c,2); 00291 $cp['reason_text']=trim($parts[1]); 00292 $cp['mailserver']='Postfix'; 00293 if (stristr($cp['reason_text'],'550')) { 00294 $cp['reason']=550; // 550 Invalid recipient, User unknown 00295 } elseif (stristr($cp['reason_text'],'553')) { 00296 $cp['reason']=553; // No such user 00297 } elseif (stristr($cp['reason_text'],'551')) { 00298 $cp['reason']=551; // Mailbox full 00299 } else { 00300 $cp['reason']=-1; 00301 } 00302 } else { // No-named: 00303 $cp['content']=trim($c); 00304 $cp['reason_text']=trim(substr($c,0,1000)); 00305 $cp['mailserver']='unknown'; 00306 if (eregi('Unknown Recipient|Delivery failed 550|Receiver not found|User not listed|recipient problem|Delivery to the following recipients failed|User unknown|recipient name is not recognized',$cp['reason_text'])) { 00307 $cp['reason']=550; // 550 Invalid recipient, User unknown 00308 } elseif (eregi('over quota|mailbox full',$cp['reason_text'])) { 00309 $cp['reason']=551; 00310 } elseif (eregi('Error in Header',$cp['reason_text'])) { 00311 $cp['reason']=554; 00312 } else { 00313 $cp['reason']=-1; 00314 } 00315 } 00316 00317 return $cp; 00318 } 00319 00326 function decodeHeaderString($str) { 00327 $parts = explode('=?',$str,2); 00328 if (count($parts)==2) { 00329 list($charset,$encType,$encContent)=explode('?',$parts[1],3); 00330 $subparts =explode('?=',$encContent,2); 00331 $encContent=$subparts[0]; 00332 00333 switch(strtolower($encType)) { 00334 case 'q': 00335 $encContent = quoted_printable_decode($encContent); 00336 $encContent = str_replace('_',' ',$encContent); 00337 break; 00338 case 'b': 00339 $encContent=base64_decode($encContent); 00340 break; 00341 } 00342 00343 $parts[1]=$encContent.$this->decodeHeaderString($subparts[1]); // Calls decodeHeaderString recursively for any subsequent encoded section. 00344 } 00345 return implode('',$parts); 00346 } 00347 00354 function extractNameEmail($str) { 00355 $outArr=array(); 00356 00357 // Email: 00358 $reg=''; 00359 ereg('<([^>]*)>',$str,$reg); 00360 if (t3lib_div::validEmail($str)) { 00361 $outArr['email']=$str; 00362 } elseif ($reg[1] && t3lib_div::validEmail($reg[1])) { 00363 $outArr['email']=$reg[1]; 00364 // Find name: 00365 list($namePart)=explode($reg[0],$str); 00366 if (trim($namePart)) { 00367 $reg=''; 00368 ereg('"([^"]*)"',$str,$reg); 00369 if (trim($reg[1])) { 00370 $outArr['name']=trim($reg[1]); 00371 } else $outArr['name']=trim($namePart); 00372 } 00373 } 00374 return $outArr; 00375 } 00376 00383 function getContentTypeData($contentTypeStr) { 00384 $outValue=array(); 00385 $cTypeParts = t3lib_div::trimExplode(';',$contentTypeStr,1); 00386 $outValue['_MIME_TYPE']=$cTypeParts[0]; // content type, first value is supposed to be the mime-type, whatever after the first is something else. 00387 00388 reset($cTypeParts); 00389 next($cTypeParts); 00390 while(list(,$v)=Each($cTypeParts)) { 00391 $reg=''; 00392 eregi('([^=]*)="(.*)"',$v,$reg); 00393 if (trim($reg[1]) && trim($reg[2])) { 00394 $outValue[strtolower($reg[1])] = $reg[2]; 00395 } 00396 } 00397 return $outValue; 00398 } 00399 00406 function makeUnixDate($dateStr) { 00407 $dateParts=explode(',',$dateStr); 00408 $dateStr=count($dateParts)>1 ? $dateParts[1] : $dateParts[0]; 00409 00410 $spaceParts = t3lib_div::trimExplode(' ',$dateStr,1); 00411 00412 $spaceParts[1]=$this->dateAbbrevs[strtoupper($spaceParts[1])]; 00413 $timeParts = explode(':',$spaceParts[3]); 00414 $timeStamp = mktime ($timeParts[0], $timeParts[1], $timeParts[2], $spaceParts[1], $spaceParts[0], $spaceParts[2]); 00415 00416 $offset = $this->getGMToffset($spaceParts[4]); 00417 $timeStamp-=($offset*60); // Compensates for GMT by subtracting the number of seconds which the date is offset from serverTime 00418 00419 return $timeStamp; 00420 } 00421 00429 function getGMToffset($GMT) { 00430 $GMToffset=substr($GMT,1,2)*60+substr($GMT,3,2); 00431 $GMToffset*=substr($GMT,0,1)=='+'?1:-1; 00432 $GMToffset-=$this->serverGMToffsetMinutes; 00433 return $GMToffset; 00434 } 00435 00443 function extractMailHeader($content,$limit=0) { 00444 if ($limit) $content = substr($content,0,$limit); 00445 00446 $lines=explode(chr(10),ltrim($content)); 00447 $headers=array(); 00448 $p=''; 00449 while(list($k,$str)=each($lines)) { 00450 if (!trim($str)) break; // header finished 00451 $parts = explode(' ',$str,2); 00452 if ($parts[0] && substr($parts[0],-1)==':') { 00453 $p=strtolower(substr($parts[0],0,-1)); 00454 if (isset($headers[$p])) { 00455 $headers[$p.'.'][]=$headers[$p]; 00456 $headers[$p]=''; 00457 } 00458 $headers[$p]=trim($parts[1]); 00459 } else { 00460 $headers[$p].=' '.trim($str); 00461 } 00462 unset($lines[$k]); 00463 } 00464 if (!$limit) $headers['CONTENT']=ltrim(implode(chr(10),$lines)); 00465 return $headers; 00466 } 00467 00474 function fullParse($content) { 00475 // ************************* 00476 // PROCESSING the HEADER part of the mail 00477 // ************************* 00478 00479 // Splitting header and body of mail: 00480 $mailParts = $this->extractMailHeader($content); 00481 00482 // Decoding header values which potentially can be encoded by =?...?= 00483 $list = explode(',','subject,thread-topic,from,to'); 00484 while(list(,$headerType)=each($list)) { 00485 if (isset($mailParts[$headerType])) $mailParts[$headerType]=$this->decodeHeaderString($mailParts[$headerType]); 00486 } 00487 // Separating email/names from header fields which can contain email addresses. 00488 $list = explode(',','from,to,reply-to,sender,return-path'); 00489 while(list(,$headerType)=each($list)) { 00490 if (isset($mailParts[$headerType])) { 00491 $mailParts['_'.strtoupper($headerType)]=$this->extractNameEmail($mailParts[$headerType]); 00492 } 00493 } 00494 // Decode date from human-readable format to unix-time (includes compensation for GMT CET) 00495 $mailParts['_DATE']=$this->makeUnixDate($mailParts['date']); 00496 00497 // Transfer encodings of body content 00498 switch(strtolower($mailParts['content-transfer-encoding'])) { 00499 case 'quoted-printable': 00500 $mailParts['CONTENT']=quoted_printable_decode($mailParts['CONTENT']); 00501 break; 00502 case 'base64': 00503 $mailParts['CONTENT']=base64_decode($mailParts['CONTENT']); 00504 break; 00505 } 00506 00507 // Content types 00508 $mailParts['_CONTENT_TYPE_DAT']=$this->getContentTypeData($mailParts['content-type']); 00509 00510 00511 // ************************* 00512 // PROCESSING the CONTENT part of the mail (the body) 00513 // ************************* 00514 $cType = strtolower($mailParts['_CONTENT_TYPE_DAT']['_MIME_TYPE']); 00515 $cType = substr($cType,0,9); // only looking for 'multipart' in string. 00516 switch($cType) { 00517 /* case 'multipart/mixed': 00518 case 'multipart/related': 00519 case 'multipart/alternative': 00520 case 'multipart/signed': 00521 */ 00522 case 'multipart': 00523 if ($mailParts['_CONTENT_TYPE_DAT']['boundary']) { 00524 $contentSectionParts = t3lib_div::trimExplode('--'.$mailParts['_CONTENT_TYPE_DAT']['boundary'],$mailParts['CONTENT'],1); 00525 $contentSectionParts_proc=array(); 00526 00527 reset($contentSectionParts); 00528 while(list($k,$v)=each($contentSectionParts)) { 00529 if (substr($v,0,2)=='--') break; 00530 $contentSectionParts_proc[$k]=$this->fullParse($v); 00531 } 00532 $mailParts['CONTENT']=$contentSectionParts_proc; 00533 } else $mailParts['CONTENT'] = 'ERROR: No boundary found.'; 00534 break; 00535 default: 00536 if (strtolower($mailParts['_CONTENT_TYPE_DAT']['charset'])=='utf-8') { 00537 $mailParts['CONTENT']=utf8_decode($mailParts['CONTENT']); 00538 } 00539 break; 00540 } 00541 return $mailParts; 00542 } 00543 } 00544 00545 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_readmail.php']) { 00546 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_readmail.php']); 00547 } 00548 ?>