Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2006 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 ***************************************************************/ 00193 class t3lib_htmlmail { 00194 // Headerinfo: 00195 var $recipient = "recipient@whatever.com"; 00196 var $recipient_copy = ""; // This recipient (or list of...) will also receive the mail. Regard it as a copy. 00197 var $subject = "This is the subject"; 00198 var $from_email = "sender@php-mailer.com"; 00199 var $from_name = "Mr. Sender"; 00200 var $replyto_email = "reply@mailer.com"; 00201 var $replyto_name = "Mr. Reply"; 00202 var $organisation = "Your Company"; 00203 var $priority = 3; // 1 = highest, 5 = lowest, 3 = normal 00204 var $mailer = "PHP mailer"; // X-mailer 00205 var $alt_base64=0; 00206 var $alt_8bit=0; 00207 var $jumperURL_prefix =""; // This is a prefix that will be added to all links in the mail. Example: 'http://www.mydomain.com/jump?userid=###FIELD_uid###&url='. if used, anything after url= is urlencoded. 00208 var $jumperURL_useId=0; // If set, then the array-key of the urls are inserted instead of the url itself. Smart in order to reduce link-length 00209 var $mediaList=""; // If set, this is a list of the media-files (index-keys to the array) that should be represented in the html-mail 00210 var $http_password=""; 00211 var $http_username=""; 00212 var $postfix_version1=false; 00213 00214 // Internal 00215 00216 /* This is how the $theParts-array is normally looking 00217 var $theParts = Array( 00218 "plain" => Array ( 00219 "content"=> "" 00220 ), 00221 "html" => Array ( 00222 "content"=> "", 00223 "path" => "", 00224 "media" => Array(), 00225 "hrefs" => Array() 00226 ), 00227 "attach" => Array () 00228 ); 00229 */ 00230 var $theParts = Array(); 00231 00232 var $messageid = ""; 00233 var $returnPath = ""; 00234 var $Xid = ""; 00235 var $dontEncodeHeader = false; // If set, the header will not be encoded 00236 00237 var $headers = ""; 00238 var $message = ""; 00239 var $part=0; 00240 var $image_fullpath_list = ""; 00241 var $href_fullpath_list = ""; 00242 00243 var $plain_text_header = ''; 00244 var $html_text_header = ''; 00245 var $charset = ''; 00246 var $defaultCharset = 'iso-8859-1'; 00247 00248 00249 00250 00251 00252 00253 00254 00261 function t3lib_htmlmail () { 00262 $this->forceReturnPath = $GLOBALS['TYPO3_CONF_VARS']['SYS']['forceReturnPath']; 00263 } 00264 00268 function start () { 00269 global $TYPO3_CONF_VARS; 00270 00271 // Sets the message id 00272 $host = php_uname('n'); 00273 if (strpos('.',$host) === FALSE) { 00274 $host = gethostbyaddr(gethostbyname($host)); 00275 } 00276 if (!$host || $host == '127.0.0.1' || $host == 'localhost') { 00277 $host = ($TYPO3_CONF_VARS['SYS']['sitename'] ? preg_replace('/[^A-Za-z0-9_\-]/', '_', $TYPO3_CONF_VARS['SYS']['sitename']) : 'localhost') . '.TYPO3'; 00278 } 00279 $this->messageid = md5(microtime()) . '@' . $host; 00280 00281 // Default line break for Unix systems. 00282 $this->linebreak = chr(10); 00283 // Line break for Windows. This is needed because PHP on Windows systems send mails via SMTP instead of using sendmail, and thus the linebreak needs to be \r\n. 00284 if (TYPO3_OS=='WIN') { 00285 $this->linebreak = chr(13).chr(10); 00286 } 00287 00288 $charset = $this->defaultCharset; 00289 if (is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->config['metaCharset']) { 00290 $charset = $GLOBALS['TSFE']->config['metaCharset']; 00291 } elseif ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']) { 00292 $charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']; 00293 } 00294 $this->charset = $charset; 00295 00296 // Use quoted-printable headers by default 00297 $this->useQuotedPrintable(); 00298 } 00299 00305 function useQuotedPrintable() { 00306 $this->plain_text_header = 'Content-Type: text/plain; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: quoted-printable'; 00307 $this->html_text_header = 'Content-Type: text/html; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: quoted-printable'; 00308 } 00309 00315 function useBase64() { 00316 $this->plain_text_header = 'Content-Type: text/plain; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: base64'; 00317 $this->html_text_header = 'Content-Type: text/html; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: base64'; 00318 $this->alt_base64=1; 00319 } 00320 00326 function use8Bit() { 00327 $this->plain_text_header = 'Content-Type: text/plain; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: 8bit'; 00328 $this->html_text_header = 'Content-Type: text/html; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: 8bit'; 00329 $this->alt_8bit=1; 00330 } 00331 00338 function encodeMsg($content) { 00339 return $this->alt_base64 ? $this->makeBase64($content) : ($this->alt_8bit ? $content : t3lib_div::quoted_printable($content)); 00340 } 00341 00348 function addPlain ($content) { 00349 // Adds plain-text and qp-encodes it 00350 $content=$this->substHTTPurlsInPlainText($content); 00351 $this->setPlain($this->encodeMsg($content)); 00352 } 00353 00360 function addAttachment($file) { 00361 // Adds an attachment to the mail 00362 $theArr = $this->getExtendedURL($file); // We fetch the content and the mime-type 00363 if ($theArr) { 00364 if (!$theArr["content_type"]){$theArr["content_type"]="application/octet-stream";} 00365 $temp = $this->split_fileref($file); 00366 $theArr["filename"]= (($temp["file"])?$temp["file"]:(strpos(" ".$theArr["content_type"],"htm")?"index.html":"unknown")); 00367 $this->theParts["attach"][]=$theArr; 00368 return true; 00369 } else { return false;} 00370 } 00371 00378 function addHTML ($file) { 00379 // Adds HTML and media, encodes it from a URL or file 00380 $status = $this->fetchHTML($file); 00381 // debug(md5($status)); 00382 if (!$status) {return false;} 00383 if ($this->extractFramesInfo()) { 00384 return "Document was a frameset. Stopped"; 00385 } 00386 $this->extractMediaLinks(); 00387 $this->extractHyperLinks(); 00388 $this->fetchHTMLMedia(); 00389 $this->substMediaNamesInHTML(0); // 0 = relative 00390 $this->substHREFsInHTML(); 00391 $this->setHTML($this->encodeMsg($this->theParts["html"]["content"])); 00392 } 00393 00401 function extractHtmlInit($html,$url) { 00402 $this->theParts["html"]["content"]=$html; 00403 $this->theParts["html"]["path"]=$url; 00404 } 00405 00412 function send($recipient) { 00413 // This function sends the mail to one $recipient 00414 if ($recipient) {$this->recipient = $recipient;} 00415 $this->setHeaders(); 00416 $this->setContent(); 00417 $this->sendTheMail(); 00418 } 00419 00420 00421 00422 00423 00424 00425 00426 00427 00428 00429 00430 00431 00432 /***************************************** 00433 * 00434 * Main functions 00435 * 00436 *****************************************/ 00437 00441 function setHeaders() { 00442 // Clears the header-string and sets the headers based on object-vars. 00443 $this->headers = ""; 00444 // Message_id 00445 $this->add_header("Message-ID: <".$this->messageid.">"); 00446 // Return path 00447 if ($this->returnPath) { 00448 $this->add_header("Return-Path: ".$this->returnPath); 00449 $this->add_header("Errors-To: ".$this->returnPath); 00450 } 00451 // X-id 00452 if ($this->Xid) { 00453 $this->add_header("X-Typo3MID: ".$this->Xid); 00454 } 00455 00456 // From 00457 if ($this->from_email) { 00458 if ($this->from_name) { 00459 $this->add_header('From: '.$this->from_name.' <'.$this->from_email.'>'); 00460 } else { 00461 $this->add_header('From: '.$this->from_email); 00462 } 00463 } 00464 // Reply 00465 if ($this->replyto_email) { 00466 if ($this->replyto_name) { 00467 $this->add_header('Reply-To: '.$this->replyto_name.' <'.$this->replyto_email.'>'); 00468 } else { 00469 $this->add_header('Reply-To: '.$this->replyto_email); 00470 } 00471 } 00472 // Organisation 00473 if ($this->organisation) { 00474 $this->add_header('Organisation: '.$this->organisation); 00475 } 00476 // mailer 00477 if ($this->mailer) { 00478 $this->add_header("X-Mailer: $this->mailer"); 00479 } 00480 // priority 00481 if ($this->priority) { 00482 $this->add_header("X-Priority: $this->priority"); 00483 } 00484 $this->add_header("Mime-Version: 1.0"); 00485 00486 if (!$this->dontEncodeHeader) { 00487 $enc = $this->alt_base64 ? 'base64' : 'quoted_printable'; // Header must be ASCII, therefore only base64 or quoted_printable are allowed! 00488 // Quote recipient and subject 00489 $this->recipient = t3lib_div::encodeHeader($this->recipient,$enc,$this->charset); 00490 $this->subject = t3lib_div::encodeHeader($this->subject,$enc,$this->charset); 00491 } 00492 } 00493 00500 function setRecipient ($recip) { 00501 // Sets the recipient(s). If you supply a string, you set one recipient. If you supply an array, every value is added as a recipient. 00502 if (is_array($recip)) { 00503 $this->recipient = ""; 00504 while (list($key,) = each($recip)) { 00505 $this->recipient .= $recip[$key].","; 00506 } 00507 $this->recipient = ereg_replace(",$","",$this->recipient); 00508 } else { 00509 $this->recipient = $recip; 00510 } 00511 } 00512 00518 function getHTMLContentType() { 00519 return count($this->theParts["html"]["media"]) ? 'multipart/related;' : 'multipart/alternative;'; 00520 } 00521 00527 function setContent() { 00528 // Begins building the message-body 00529 $this->message = ""; 00530 $boundary = $this->getBoundary(); 00531 // Setting up headers 00532 if (count($this->theParts["attach"])) { 00533 $this->add_header('Content-Type: multipart/mixed;'); 00534 $this->add_header(' boundary="'.$boundary.'"'); 00535 $this->add_message("This is a multi-part message in MIME format.\n"); 00536 $this->constructMixed($boundary); // Generate (plain/HTML) / attachments 00537 } elseif ($this->theParts["html"]["content"]) { 00538 $this->add_header('Content-Type: '.$this->getHTMLContentType()); 00539 $this->add_header(' boundary="'.$boundary.'"'); 00540 $this->add_message("This is a multi-part message in MIME format.\n"); 00541 $this->constructHTML($boundary); // Generate plain/HTML mail 00542 } else { 00543 $this->add_header($this->plain_text_header); 00544 $this->add_message($this->getContent("plain")); // Generate plain only 00545 } 00546 } 00547 00554 function constructMixed ($boundary) { 00555 // Here (plain/HTML) is combined with the attachments 00556 $this->add_message("--".$boundary); 00557 // (plain/HTML) is added 00558 if ($this->theParts["html"]["content"]) { 00559 // HTML and plain 00560 $newBoundary = $this->getBoundary(); 00561 $this->add_message("Content-Type: ".$this->getHTMLContentType()); 00562 $this->add_message(' boundary="'.$newBoundary.'"'); 00563 $this->add_message(''); 00564 $this->constructHTML($newBoundary); 00565 } else { // Purely plain 00566 $this->add_message($this->plain_text_header); 00567 $this->add_message(''); 00568 $this->add_message($this->getContent("plain")); 00569 } 00570 // attachments are added 00571 if (is_array($this->theParts["attach"])) { 00572 reset($this->theParts["attach"]); 00573 while(list(,$media)=each($this->theParts["attach"])) { 00574 $this->add_message("--".$boundary); 00575 $this->add_message("Content-Type: ".$media["content_type"]); 00576 $this->add_message(' name="'.$media["filename"].'"'); 00577 $this->add_message("Content-Transfer-Encoding: base64"); 00578 $this->add_message("Content-Disposition: attachment;"); 00579 $this->add_message(' filename="'.$media["filename"].'"'); 00580 $this->add_message(''); 00581 $this->add_message($this->makeBase64($media["content"])); 00582 } 00583 } 00584 $this->add_message("--".$boundary."--\n"); 00585 } 00586 00593 function constructHTML ($boundary) { 00594 if (count($this->theParts["html"]["media"])) { // If media, then we know, the multipart/related content-type has been set before this function call... 00595 $this->add_message("--".$boundary); 00596 // HTML has media 00597 $newBoundary = $this->getBoundary(); 00598 $this->add_message("Content-Type: multipart/alternative;"); 00599 $this->add_message(' boundary="'.$newBoundary.'"'); 00600 $this->add_message('Content-Transfer-Encoding: 7bit'); 00601 $this->add_message(''); 00602 00603 $this->constructAlternative($newBoundary); // Adding the plaintext/html mix 00604 00605 $this->constructHTML_media($boundary); 00606 } else { 00607 $this->constructAlternative($boundary); // Adding the plaintext/html mix, and if no media, then use $boundary instead of $newBoundary 00608 } 00609 } 00610 00617 function constructAlternative($boundary) { 00618 // Here plain is combined with HTML 00619 $this->add_message("--".$boundary); 00620 // plain is added 00621 $this->add_message($this->plain_text_header); 00622 $this->add_message(''); 00623 $this->add_message($this->getContent("plain")); 00624 $this->add_message("--".$boundary); 00625 // html is added 00626 $this->add_message($this->html_text_header); 00627 $this->add_message(''); 00628 $this->add_message($this->getContent("html")); 00629 $this->add_message("--".$boundary."--\n"); 00630 } 00631 00638 function constructHTML_media ($boundary) { 00639 /* // Constructs the HTML-part of message if the HTML contains media 00640 $this->add_message("--".$boundary); 00641 // htmlcode is added 00642 $this->add_message($this->html_text_header); 00643 $this->add_message(''); 00644 $this->add_message($this->getContent("html")); 00645 00646 OLD stuf... 00647 00648 */ 00649 // media is added 00650 if (is_array($this->theParts["html"]["media"])) { 00651 reset($this->theParts["html"]["media"]); 00652 while(list($key,$media)=each($this->theParts["html"]["media"])) { 00653 if (!$this->mediaList || t3lib_div::inList($this->mediaList,$key)) { 00654 $this->add_message("--".$boundary); 00655 $this->add_message("Content-Type: ".$media["ctype"]); 00656 $this->add_message("Content-ID: <part".$key.".".$this->messageid.">"); 00657 $this->add_message("Content-Transfer-Encoding: base64"); 00658 $this->add_message(''); 00659 $this->add_message($this->makeBase64($media["content"])); 00660 } 00661 } 00662 } 00663 $this->add_message("--".$boundary."--\n"); 00664 } 00665 00691 function sendTheMail () { 00692 #debug(array($this->recipient,$this->subject,$this->message,$this->headers)); 00693 // Sends the mail, requires the recipient, message and headers to be set. 00694 if (trim($this->recipient) && trim($this->message)) { // && trim($this->headers) 00695 $returnPath = (strlen($this->returnPath)>0)?"-f".$this->returnPath:''; 00696 //On windows the -f flag is not used (specific for Sendmail and Postfix), but instead the php.ini parameter sendmail_from is used. 00697 if($this->returnPath) { 00698 ini_set(sendmail_from, $this->returnPath); 00699 } 00700 //If safe mode is on, the fifth parameter to mail is not allowed, so the fix wont work on unix with safe_mode=On 00701 if(!ini_get('safe_mode') && $this->forceReturnPath) { 00702 mail($this->recipient, 00703 $this->subject, 00704 $this->message, 00705 $this->headers, 00706 $returnPath); 00707 } else { 00708 mail($this->recipient, 00709 $this->subject, 00710 $this->message, 00711 $this->headers); 00712 } 00713 // Sending copy: 00714 if ($this->recipient_copy) { 00715 if(!ini_get('safe_mode') && $this->forceReturnPath) { 00716 mail( $this->recipient_copy, 00717 $this->subject, 00718 $this->message, 00719 $this->headers, 00720 $returnPath); 00721 } else { 00722 mail( $this->recipient_copy, 00723 $this->subject, 00724 $this->message, 00725 $this->headers ); 00726 } 00727 } 00728 // Auto response 00729 if ($this->auto_respond_msg) { 00730 $theParts = explode('/',$this->auto_respond_msg,2); 00731 $theParts[1] = str_replace("/",chr(10),$theParts[1]); 00732 if(!ini_get('safe_mode') && $this->forceReturnPath) { 00733 mail( $this->from_email, 00734 $theParts[0], 00735 $theParts[1], 00736 "From: ".$this->recipient, 00737 $returnPath); 00738 } else { 00739 mail( $this->from_email, 00740 $theParts[0], 00741 $theParts[1], 00742 "From: ".$this->recipient); 00743 } 00744 } 00745 if($this->returnPath) { 00746 ini_restore(sendmail_from); 00747 } 00748 return true; 00749 } else {return false;} 00750 } 00751 00757 function getBoundary() { 00758 // Returns boundaries 00759 $this->part++; 00760 return "----------".uniqid("part_".$this->part."_"); 00761 } 00762 00769 function setPlain ($content) { 00770 // Sets the plain-text part. No processing done. 00771 $this->theParts["plain"]["content"] = $content; 00772 } 00773 00780 function setHtml ($content) { 00781 // Sets the HTML-part. No processing done. 00782 $this->theParts["html"]["content"] = $content; 00783 } 00784 00791 function add_header($header) { 00792 if (!$this->dontEncodeHeader && !stristr($header,'Content-Type') && !stristr($header,'Content-Transfer-Encoding')) { 00793 // Mail headers must be ASCII, therefore we convert the whole header to either base64 or quoted_printable 00794 $parts = explode(': ',$header,2); // Field tags must not be encoded 00795 if (count($parts)==2) { 00796 $enc = $this->alt_base64 ? 'base64' : 'quoted_printable'; 00797 $parts[1] = t3lib_div::encodeHeader($parts[1],$enc,$this->charset); 00798 $header = implode(': ',$parts); 00799 } 00800 } 00801 00802 // Adds a header to the mail. Use this AFTER the setHeaders()-function 00803 $this->headers.=$header."\n"; 00804 } 00805 00812 function add_message($string) { 00813 // Adds a line of text to the mail-body. Is normally use internally 00814 $this->message.=$string."\n"; 00815 } 00816 00823 function getContent($type) { 00824 return $this->theParts[$type]["content"]; 00825 } 00826 00832 function preview() { 00833 echo nl2br(HTMLSpecialChars($this->headers)); 00834 echo "<BR>"; 00835 echo nl2br(HTMLSpecialChars($this->message)); 00836 } 00837 00838 00839 00840 00841 00842 00843 00844 00845 00846 00847 00848 00849 00850 /**************************************************** 00851 * 00852 * Functions for acquiring attachments, HTML, analyzing and so on ** 00853 * 00854 ***************************************************/ 00855 00860 function fetchHTML($file) { 00861 // Fetches the HTML-content from either url og local serverfile 00862 $this->theParts["html"]["content"] = $this->getURL($file); // Fetches the content of the page 00863 if ($this->theParts["html"]["content"]) { 00864 $addr = $this->extParseUrl($file); 00865 $path = ($addr['scheme']) ? $addr['scheme'].'://'.$addr['host'].(($addr['port'])?':'.$addr['port']:'').(($addr['filepath'])?$addr['filepath']:'/') : $addr['filepath']; 00866 $this->theParts["html"]["path"] = $path; 00867 return true; 00868 } else { 00869 return false; 00870 } 00871 } 00872 00878 function fetchHTMLMedia() { 00879 // Fetches the mediafiles which are found by extractMediaLinks() 00880 if (is_array($this->theParts["html"]["media"])) { 00881 reset ($this->theParts["html"]["media"]); 00882 if (count($this->theParts["html"]["media"]) > 0) { 00883 while (list($key,$media) = each ($this->theParts["html"]["media"])) { 00884 $picdata = $this->getExtendedURL($this->theParts["html"]["media"][$key]["absRef"]); // We fetch the content and the mime-type 00885 if (is_array($picdata)) { 00886 $this->theParts["html"]["media"][$key]["content"] = $picdata["content"]; 00887 $this->theParts["html"]["media"][$key]["ctype"] = $picdata["content_type"]; 00888 } 00889 } 00890 } 00891 } 00892 } 00893 00899 function extractMediaLinks() { 00900 // extracts all media-links from $this->theParts["html"]["content"] 00901 $html_code = $this->theParts["html"]["content"]; 00902 $attribRegex = $this->tag_regex(Array("img","table","td","tr","body","iframe","script","input","embed")); 00903 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00904 $len=strlen($codepieces[0]); 00905 $pieces = count($codepieces); 00906 $reg = array(); 00907 for($i=1; $i < $pieces; $i++) { 00908 $tag = strtolower(strtok(substr($html_code,$len+1,10)," ")); 00909 $len+=strlen($tag)+strlen($codepieces[$i])+2; 00910 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00911 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00912 $imageData=array(); 00913 $imageData["ref"]=($attributes["src"]) ? $attributes["src"] : $attributes["background"]; // Finds the src or background attribute 00914 if ($imageData["ref"]) { 00915 $imageData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $imageData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00916 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00917 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00918 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00919 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00920 $imageData["tag"]=$tag; 00921 $imageData["use_jumpurl"]=$attributes["dmailerping"]?1:0; 00922 $this->theParts["html"]["media"][]=$imageData; 00923 } 00924 } 00925 } 00926 // Extracts stylesheets 00927 $attribRegex = $this->tag_regex(Array("link")); 00928 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00929 $pieces = count($codepieces); 00930 for($i=1; $i < $pieces; $i++) { 00931 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00932 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00933 $imageData=array(); 00934 if (strtolower($attributes["rel"])=="stylesheet" && $attributes["href"]) { 00935 $imageData["ref"]=$attributes["href"]; // Finds the src or background attribute 00936 $imageData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $imageData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00937 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00938 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00939 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00940 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00941 $this->theParts["html"]["media"][]=$imageData; 00942 } 00943 } 00944 } 00945 // fixes javascript rollovers 00946 $codepieces = split(quotemeta(".src"), $html_code); 00947 $pieces = count($codepieces); 00948 $expr = "^[^".quotemeta("\"").quotemeta("'")."]*"; 00949 for($i=1; $i < $pieces; $i++) { 00950 $temp = $codepieces[$i]; 00951 $temp = trim(ereg_replace("=","",trim($temp))); 00952 ereg ($expr,substr($temp,1,strlen($temp)),$reg); 00953 $imageData["ref"] = $reg[0]; 00954 $imageData["quotes"] = substr($temp,0,1); 00955 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00956 $theInfo = $this->split_fileref($imageData["ref"]); 00957 switch ($theInfo["fileext"]) { 00958 case "gif": 00959 case "jpeg": 00960 case "jpg": 00961 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00962 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00963 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00964 $this->theParts["html"]["media"][]=$imageData; 00965 } 00966 break; 00967 } 00968 } 00969 } 00970 00976 function extractHyperLinks() { 00977 // extracts all hyper-links from $this->theParts["html"]["content"] 00978 $html_code = $this->theParts["html"]["content"]; 00979 $attribRegex = $this->tag_regex(Array("a","form","area")); 00980 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00981 $len=strlen($codepieces[0]); 00982 $pieces = count($codepieces); 00983 for($i=1; $i < $pieces; $i++) { 00984 $tag = strtolower(strtok(substr($html_code,$len+1,10)," ")); 00985 $len+=strlen($tag)+strlen($codepieces[$i])+2; 00986 00987 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00988 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00989 $hrefData=""; 00990 if ($attributes["href"]) {$hrefData["ref"]=$attributes["href"];} else {$hrefData["ref"]=$attributes["action"];} 00991 if ($hrefData["ref"]) { 00992 $hrefData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $hrefData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00993 $hrefData["subst_str"] = $hrefData["quotes"].$hrefData["ref"].$hrefData["quotes"]; // subst_str is the string to look for, when substituting lateron 00994 if ($hrefData["ref"] && substr(trim($hrefData["ref"]),0,1)!="#" && !strstr($this->href_fullpath_list,"|".$hrefData["subst_str"]."|")) { 00995 $this->href_fullpath_list.="|".$hrefData["subst_str"]."|"; 00996 $hrefData["absRef"] = $this->absRef($hrefData["ref"]); 00997 $hrefData["tag"]=$tag; 00998 $this->theParts["html"]["hrefs"][]=$hrefData; 00999 } 01000 } 01001 } 01002 // Extracts TYPO3 specific links made by the openPic() JS function 01003 $codepieces = explode("onClick=\"openPic('", $html_code); 01004 $pieces = count($codepieces); 01005 for($i=1; $i < $pieces; $i++) { 01006 $showpic_linkArr = explode("'",$codepieces[$i]); 01007 $hrefData["ref"]=$showpic_linkArr[0]; 01008 if ($hrefData["ref"]) { 01009 $hrefData["quotes"]="'"; // Finds out if the value had quotes around it 01010 $hrefData["subst_str"] = $hrefData["quotes"].$hrefData["ref"].$hrefData["quotes"]; // subst_str is the string to look for, when substituting lateron 01011 if ($hrefData["ref"] && !strstr($this->href_fullpath_list,"|".$hrefData["subst_str"]."|")) { 01012 $this->href_fullpath_list.="|".$hrefData["subst_str"]."|"; 01013 $hrefData["absRef"] = $this->absRef($hrefData["ref"]); 01014 $this->theParts["html"]["hrefs"][]=$hrefData; 01015 } 01016 } 01017 } 01018 } 01019 01025 function extractFramesInfo() { 01026 // extracts all media-links from $this->theParts["html"]["content"] 01027 $html_code = $this->theParts["html"]["content"]; 01028 if (strpos(" ".$html_code,"<frame ")) { 01029 $attribRegex = $this->tag_regex("frame"); 01030 $codepieces = split($attribRegex, $html_code, 1000000 ); // Splits the document by the beginning of the above tags 01031 $pieces = count($codepieces); 01032 for($i=1; $i < $pieces; $i++) { 01033 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 01034 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 01035 $frame=""; 01036 $frame["src"]=$attributes["src"]; 01037 $frame["name"]=$attributes["name"]; 01038 $frame["absRef"] = $this->absRef($frame["src"]); 01039 $theInfo[] = $frame; 01040 } 01041 return $theInfo; 01042 } 01043 } 01044 01051 function substMediaNamesInHTML($absolute) { 01052 // This substitutes the media-references in $this->theParts["html"]["content"] 01053 // If $absolute is true, then the refs are substituted with http:// ref's indstead of Content-ID's (cid). 01054 if (is_array($this->theParts["html"]["media"])) { 01055 reset ($this->theParts["html"]["media"]); 01056 while (list($key,$val) = each ($this->theParts["html"]["media"])) { 01057 if ($val["use_jumpurl"] && $this->jumperURL_prefix) { 01058 $theSubstVal = $this->jumperURL_prefix.t3lib_div::rawUrlEncodeFP($val['absRef']); 01059 } else { 01060 $theSubstVal = ($absolute) ? $val["absRef"] : "cid:part".$key.".".$this->messageid; 01061 } 01062 $this->theParts["html"]["content"] = str_replace( 01063 $val["subst_str"], 01064 $val["quotes"].$theSubstVal.$val["quotes"], 01065 $this->theParts["html"]["content"] ); 01066 } 01067 } 01068 if (!$absolute) { 01069 $this->fixRollOvers(); 01070 } 01071 } 01072 01078 function substHREFsInHTML() { 01079 // This substitutes the hrefs in $this->theParts["html"]["content"] 01080 if (is_array($this->theParts["html"]["hrefs"])) { 01081 reset ($this->theParts["html"]["hrefs"]); 01082 while (list($key,$val) = each ($this->theParts["html"]["hrefs"])) { 01083 if ($this->jumperURL_prefix && $val["tag"]!="form") { // Form elements cannot use jumpurl! 01084 if ($this->jumperURL_useId) { 01085 $theSubstVal = $this->jumperURL_prefix.$key; 01086 } else { 01087 $theSubstVal = $this->jumperURL_prefix.t3lib_div::rawUrlEncodeFP($val['absRef']); 01088 } 01089 } else { 01090 $theSubstVal = $val["absRef"]; 01091 } 01092 $this->theParts["html"]["content"] = str_replace( 01093 $val["subst_str"], 01094 $val["quotes"].$theSubstVal.$val["quotes"], 01095 $this->theParts["html"]["content"] ); 01096 } 01097 } 01098 } 01099 01106 function substHTTPurlsInPlainText($content) { 01107 // This substitutes the http:// urls in plain text with links 01108 if ($this->jumperURL_prefix) { 01109 $textpieces = explode("http://", $content); 01110 $pieces = count($textpieces); 01111 $textstr = $textpieces[0]; 01112 for($i=1; $i<$pieces; $i++) { 01113 $len=strcspn($textpieces[$i],chr(32).chr(9).chr(13).chr(10)); 01114 if (trim(substr($textstr,-1))=="" && $len) { 01115 $lastChar=substr($textpieces[$i],$len-1,1); 01116 if (!ereg("[A-Za-z0-9\/#]",$lastChar)) {$len--;} // Included "\/" 3/12 01117 01118 $parts[0]="http://".substr($textpieces[$i],0,$len); 01119 $parts[1]=substr($textpieces[$i],$len); 01120 01121 if ($this->jumperURL_useId) { 01122 $this->theParts["plain"]["link_ids"][$i]=$parts[0]; 01123 $parts[0] = $this->jumperURL_prefix."-".$i; 01124 } else { 01125 $parts[0] = $this->jumperURL_prefix.t3lib_div::rawUrlEncodeFP($parts[0]); 01126 } 01127 $textstr.=$parts[0].$parts[1]; 01128 } else { 01129 $textstr.='http://'.$textpieces[$i]; 01130 } 01131 } 01132 $content = $textstr; 01133 } 01134 return $content; 01135 } 01136 01142 function fixRollOvers() { 01143 // JavaScript rollOvers cannot support graphics inside of mail. If these exists we must let them refer to the absolute url. By the way: Roll-overs seems to work only on some mail-readers and so far I've seen it work on Netscape 4 message-center (but not 4.5!!) 01144 $theNewContent = ""; 01145 $theSplit = explode(".src",$this->theParts["html"]["content"]); 01146 if (count($theSplit)>1) { 01147 while(list($key,$part)=each($theSplit)) { 01148 $sub = substr($part,0,200); 01149 if (ereg("cid:part[^ \"']*",$sub,$reg)) { 01150 $thePos = strpos($part,$reg[0]); // The position of the string 01151 ereg("cid:part([^\.]*).*",$sub,$reg2); // Finds the id of the media... 01152 $theSubStr = $this->theParts["html"]["media"][intval($reg2[1])]["absRef"]; 01153 if ($thePos && $theSubStr) { // ... and substitutes the javaScript rollover image with this instead 01154 if (!strpos(" ".$theSubStr,"http://")) {$theSubStr = "http://";} // If the path is NOT and url, the reference is set to nothing 01155 $part = substr($part,0,$thePos).$theSubStr.substr($part,$thePos+strlen($reg[0]),strlen($part)); 01156 } 01157 } 01158 $theNewContent.= $part.((($key+1)!=count($theSplit))? ".src" : "" ); 01159 } 01160 $this->theParts["html"]["content"]=$theNewContent; 01161 } 01162 } 01163 01164 01165 01166 01167 01168 01169 01170 01171 01172 01173 01174 01175 01176 01177 01178 01179 /******************************************* 01180 * 01181 * File and URL-functions 01182 * 01183 *******************************************/ 01184 01189 function makeBase64($inputstr) { 01190 // Returns base64-encoded content, which is broken every 76 character 01191 return chunk_split(base64_encode($inputstr)); 01192 } 01193 01200 function getExtendedURL($url) { 01201 // reads the URL or file and determines the Content-type by either guessing or opening a connection to the host 01202 $res["content"] = $this->getURL($url); 01203 if (!$res["content"]) {return false;} 01204 $pathInfo = parse_url($url); 01205 $fileInfo = $this->split_fileref($pathInfo["path"]); 01206 if ($fileInfo["fileext"] == "gif") {$res["content_type"] = "image/gif";} 01207 if ($fileInfo["fileext"] == "jpg" || $fileInfo["fileext"] == "jpeg") {$res["content_type"] = "image/jpeg";} 01208 if ($fileInfo['fileext'] == 'png') {$res['content_type'] = 'image/png';} 01209 if ($fileInfo["fileext"] == "html" || $fileInfo["fileext"] == "htm") {$res["content_type"] = "text/html";} 01210 if ($fileInfo['fileext'] == 'css') {$res['content_type'] = 'text/css';} 01211 if ($fileInfo["fileext"] == "swf") {$res["content_type"] = "application/x-shockwave-flash";} 01212 if (!$res["content_type"]) {$res["content_type"] = $this->getMimeType($url);} 01213 return $res; 01214 } 01215 01222 function addUserPass($url) { 01223 $user=$this->http_username; 01224 $pass=$this->http_password; 01225 $matches = array(); 01226 if ($user && $pass && preg_match('/^(https?:\/\/)/', $url, $matches)) { 01227 $url = $matches[1].$user.':'.$pass.'@'.substr($url,strlen($matches[1])); 01228 } 01229 return $url; 01230 } 01231 01238 function getURL($url) { 01239 $url = $this->addUserPass($url); 01240 // reads a url or file 01241 return t3lib_div::getURL($url); 01242 } 01243 01250 function getStrippedURL($url) { 01251 // reads a url or file and strips the HTML-tags AND removes all empty lines. This is used to read plain-text out of a HTML-page 01252 if($fd = fopen($url,"rb")) { 01253 $content = ""; 01254 while (!feof($fd)) { 01255 $line = fgetss($fd, 5000); 01256 if (trim($line)) { 01257 $content.=trim($line)."\n"; 01258 } 01259 } 01260 fclose( $fd ); 01261 return $content; 01262 } 01263 } 01264 01271 function getMimeType($url) { 01272 // Opens a connection to the server and returns the mime-type of the file 01273 // takes url only 01274 $pathInfo = parse_url($url); 01275 if (!$pathInfo["scheme"]) {return false;} 01276 $getAdr = ($pathInfo["query"])?$pathInfo["path"]."?".$pathInfo["query"]:$pathInfo["path"]; 01277 $fp = fsockopen($pathInfo['host'], ($pathInfo['port']?$pathInfo['port']:80), $errno, $errstr); 01278 if(!$fp) { 01279 return false; 01280 } else { 01281 fputs($fp,'HEAD '.$getAdr.' HTTP/1.0\r\nHost: '.$pathInfo['host'].'\r\n\r\n'); 01282 while(!feof($fp)) { 01283 $thePortion= fgets($fp,128); 01284 if (eregi("(^Content-Type: )(.*)",trim($thePortion), $reg)) { 01285 $res = trim($reg[2]); 01286 break; 01287 } 01288 } 01289 fclose($fp); 01290 } 01291 return $res; 01292 } 01293 01300 function absRef($ref) { 01301 // Returns the absolute address of a link. This is based on $this->theParts["html"]["path"] being the root-address 01302 $ref = trim($ref); 01303 $urlINFO = parse_url($ref); 01304 if ($urlINFO["scheme"]) { 01305 return $ref; 01306 } elseif (eregi("^/",$ref)){ 01307 $addr = parse_url($this->theParts["html"]["path"]); 01308 return $addr['scheme'].'://'.$addr['host'].($addr['port']?':'.$addr['port']:'').$ref; 01309 } else { 01310 return $this->theParts["html"]["path"].$ref; // If the reference is relative, the path is added, in order for us to fetch the content 01311 } 01312 } 01313 01320 function split_fileref($fileref) { 01321 // Returns an array with path, filename, filebody, fileext. 01322 if ( ereg("(.*/)(.*)$",$fileref,$reg) ) { 01323 $info["path"] = $reg[1]; 01324 $info["file"] = $reg[2]; 01325 } else { 01326 $info["path"] = ""; 01327 $info["file"] = $fileref; 01328 } 01329 $reg=""; 01330 if ( ereg("(.*)\.([^\.]*$)",$info["file"],$reg) ) { 01331 $info["filebody"] = $reg[1]; 01332 $info["fileext"] = strtolower($reg[2]); 01333 $info["realFileext"] = $reg[2]; 01334 } else { 01335 $info["filebody"] = $info["file"]; 01336 $info["fileext"] = ""; 01337 } 01338 return $info; 01339 } 01340 01347 function extParseUrl($path) { 01348 // Returns an array with file or url-information 01349 $res = parse_url($path); 01350 ereg("(.*/)([^/]*)$",$res["path"],$reg); 01351 $res["filepath"]=$reg[1]; 01352 $res["filename"]=$reg[2]; 01353 return $res; 01354 } 01355 01362 function tag_regex($tagArray) { 01363 if (!is_array($tagArray)) { 01364 $tagArray=Array($tagArray); 01365 } 01366 $theRegex = ""; 01367 $c=count($tagArray); 01368 while(list(,$tag)=each($tagArray)) { 01369 $c--; 01370 $theRegex.="<".sql_regcase($tag)."[[:space:]]".(($c)?"|":""); 01371 } 01372 return $theRegex; 01373 } 01374 01384 function get_tag_attributes($tag) { 01385 $attributes = Array(); 01386 $tag = ltrim(eregi_replace ("^<[^ ]*","",trim($tag))); 01387 $tagLen = strlen($tag); 01388 $safetyCounter = 100; 01389 // Find attribute 01390 while ($tag) { 01391 $value = ""; 01392 $reg = split("[[:space:]=>]",$tag,2); 01393 $attrib = $reg[0]; 01394 01395 $tag = ltrim(substr($tag,strlen($attrib),$tagLen)); 01396 if (substr($tag,0,1)=="=") { 01397 $tag = ltrim(substr($tag,1,$tagLen)); 01398 if (substr($tag,0,1)=='"') { // Quotes around the value 01399 $reg = explode('"',substr($tag,1,$tagLen),2); 01400 $tag = ltrim($reg[1]); 01401 $value = $reg[0]; 01402 } else { // No qoutes around value 01403 ereg("^([^[:space:]>]*)(.*)",$tag,$reg); 01404 $value = trim($reg[1]); 01405 $tag = ltrim($reg[2]); 01406 if (substr($tag,0,1)==">") { 01407 $tag =""; 01408 } 01409 } 01410 } 01411 $attributes[strtolower($attrib)]=$value; 01412 $safetyCounter--; 01413 if ($safetyCounter<0) {break;} 01414 } 01415 return $attributes; 01416 } 01417 01426 function quoted_printable($string) { 01427 return t3lib_div::quoted_printable($string, 76); 01428 } 01429 01437 function convertName($name) { 01438 return $name; 01439 } 01440 } 01441 01442 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_htmlmail.php']) { 01443 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_htmlmail.php']); 01444 } 01445 ?>