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 ***************************************************************/ 00191 class t3lib_htmlmail { 00192 // Headerinfo: 00193 var $recipient = "recipient@whatever.com"; 00194 var $recipient_copy = ""; // This recipient (or list of...) will also receive the mail. Regard it as a copy. 00195 var $subject = "This is the subject"; 00196 var $from_email = "sender@php-mailer.com"; 00197 var $from_name = "Mr. Sender"; 00198 var $replyto_email = "reply@mailer.com"; 00199 var $replyto_name = "Mr. Reply"; 00200 var $organisation = "Your Company"; 00201 var $priority = 3; // 1 = highest, 5 = lowest, 3 = normal 00202 var $mailer = "PHP mailer"; // X-mailer 00203 var $alt_base64=0; 00204 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. 00205 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 00206 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 00207 var $http_password=""; 00208 var $http_username=""; 00209 var $postfix_version1=false; 00210 00211 // Internal 00212 00213 /* This is how the $theParts-array is normally looking 00214 var $theParts = Array( 00215 "plain" => Array ( 00216 "content"=> "" 00217 ), 00218 "html" => Array ( 00219 "content"=> "", 00220 "path" => "", 00221 "media" => Array(), 00222 "hrefs" => Array() 00223 ), 00224 "attach" => Array () 00225 ); 00226 */ 00227 var $theParts = Array(); 00228 00229 var $messageid = ""; 00230 var $returnPath = ""; 00231 var $Xid = ""; 00232 00233 var $headers = ""; 00234 var $message = ""; 00235 var $part=0; 00236 var $image_fullpath_list = ""; 00237 var $href_fullpath_list = ""; 00238 00239 var $plain_text_header = "Content-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: quoted-printable"; 00240 var $html_text_header = "Content-Type: text/html; charset=iso-8859-1\nContent-Transfer-Encoding: quoted-printable"; 00241 00242 00243 00244 00245 00246 00247 00248 00255 function t3lib_htmlmail () { 00256 $this->forceReturnPath = $GLOBALS['TYPO3_CONF_VARS']['SYS']['forceReturnPath']; 00257 } 00258 00262 function start () { 00263 // Sets the message id 00264 $this->messageid = md5(microtime()).'@domain.tld'; 00265 00266 } 00267 00273 function useBase64() { 00274 $this->plain_text_header = 'Content-Type: text/plain; charset=iso-8859-1'.chr(10).'Content-Transfer-Encoding: base64'; 00275 $this->html_text_header = 'Content-Type: text/html; charset=iso-8859-1'.chr(10).'Content-Transfer-Encoding: base64'; 00276 $this->alt_base64=1; 00277 } 00278 00285 function encodeMsg($content) { 00286 return $this->alt_base64 ? $this->makeBase64($content) : t3lib_div::quoted_printable($content, 76); 00287 } 00288 00295 function addPlain ($content) { 00296 // Adds plain-text and qp-encodes it 00297 $content=$this->substHTTPurlsInPlainText($content); 00298 $this->setPlain($this->encodeMsg($content)); 00299 } 00300 00307 function addAttachment($file) { 00308 // Adds an attachment to the mail 00309 $theArr = $this->getExtendedURL($file); // We fetch the content and the mime-type 00310 if ($theArr) { 00311 if (!$theArr["content_type"]){$theArr["content_type"]="application/octet-stream";} 00312 $temp = $this->split_fileref($file); 00313 $theArr["filename"]= (($temp["file"])?$temp["file"]:(strpos(" ".$theArr["content_type"],"htm")?"index.html":"unknown")); 00314 $this->theParts["attach"][]=$theArr; 00315 return true; 00316 } else { return false;} 00317 } 00318 00325 function addHTML ($file) { 00326 // Adds HTML and media, encodes it from a URL or file 00327 $status = $this->fetchHTML($file); 00328 // debug(md5($status)); 00329 if (!$status) {return false;} 00330 if ($this->extractFramesInfo()) { 00331 return "Document was a frameset. Stopped"; 00332 } 00333 $this->extractMediaLinks(); 00334 $this->extractHyperLinks(); 00335 $this->fetchHTMLMedia(); 00336 $this->substMediaNamesInHTML(0); // 0 = relative 00337 $this->substHREFsInHTML(); 00338 $this->setHTML($this->encodeMsg($this->theParts["html"]["content"])); 00339 } 00340 00348 function extractHtmlInit($html,$url) { 00349 $this->theParts["html"]["content"]=$html; 00350 $this->theParts["html"]["path"]=$url; 00351 } 00352 00359 function send($recipient) { 00360 // This function sends the mail to one $recipient 00361 if ($recipient) {$this->recipient = $recipient;} 00362 $this->setHeaders(); 00363 $this->setContent(); 00364 $this->sendTheMail(); 00365 } 00366 00367 00368 00369 00370 00371 00372 00373 00374 00375 00376 00377 00378 00379 /***************************************** 00380 * 00381 * Main functions 00382 * 00383 *****************************************/ 00384 00388 function setHeaders () { 00389 // Clears the header-string and sets the headers based on object-vars. 00390 $this->headers = ""; 00391 // Message_id 00392 $this->add_header("Message-ID: <".$this->messageid.">"); 00393 // Return path 00394 if ($this->returnPath) { 00395 $this->add_header("Return-Path: ".$this->returnPath); 00396 } 00397 // X-id 00398 if ($this->Xid) { 00399 $this->add_header("X-Typo3MID: ".$this->Xid); 00400 } 00401 00402 // From 00403 if ($this->from_email) { 00404 if ($this->from_name) { 00405 $name = $this->convertName($this->from_name); 00406 $this->add_header('From: '.$name.' <'.$this->from_email.'>'); 00407 } else { 00408 $this->add_header('From: '.$this->from_email); 00409 } 00410 } 00411 // Reply 00412 if ($this->replyto_email) { 00413 if ($this->replyto_name) { 00414 $name = $this->convertName($this->replyto_name); 00415 $this->add_header("Reply-To: $name <$this->replyto_email>"); 00416 } else { 00417 $this->add_header("Reply-To: $this->replyto_email"); 00418 } 00419 } 00420 // Organisation 00421 if ($this->organisation) { 00422 $name = $this->convertName($this->organisation); 00423 $this->add_header("Organisation: $name"); 00424 } 00425 // mailer 00426 if ($this->mailer) { 00427 $this->add_header("X-Mailer: $this->mailer"); 00428 } 00429 // priority 00430 if ($this->priority) { 00431 $this->add_header("X-Priority: $this->priority"); 00432 } 00433 $this->add_header("Mime-Version: 1.0"); 00434 } 00435 00442 function setRecipient ($recip) { 00443 // 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. 00444 if (is_array($recip)) { 00445 $this->recipient = ""; 00446 while (list($key,) = each($recip)) { 00447 $this->recipient .= $recip[$key].","; 00448 } 00449 $this->recipient = ereg_replace(",$","",$this->recipient); 00450 } else { 00451 $this->recipient = $recip; 00452 } 00453 } 00454 00460 function getHTMLContentType() { 00461 return count($this->theParts["html"]["media"]) ? 'multipart/related;' : 'multipart/alternative;'; 00462 } 00463 00469 function setContent() { 00470 // Begins building the message-body 00471 $this->message = ""; 00472 $boundary = $this->getBoundary(); 00473 // Setting up headers 00474 if (count($this->theParts["attach"])) { 00475 $this->add_header('Content-Type: multipart/mixed;'); 00476 $this->add_header(' boundary="'.$boundary.'"'); 00477 $this->add_message("This is a multi-part message in MIME format.\n"); 00478 $this->constructMixed($boundary); // Generate (plain/HTML) / attachments 00479 } elseif ($this->theParts["html"]["content"]) { 00480 $this->add_header('Content-Type: '.$this->getHTMLContentType()); 00481 $this->add_header(' boundary="'.$boundary.'"'); 00482 $this->add_message("This is a multi-part message in MIME format.\n"); 00483 $this->constructHTML($boundary); // Generate plain/HTML mail 00484 } else { 00485 $this->add_header($this->plain_text_header); 00486 $this->add_message($this->getContent("plain")); // Generate plain only 00487 } 00488 } 00489 00496 function constructMixed ($boundary) { 00497 // Here (plain/HTML) is combined with the attachments 00498 $this->add_message("--".$boundary); 00499 // (plain/HTML) is added 00500 if ($this->theParts["html"]["content"]) { 00501 // HTML and plain 00502 $newBoundary = $this->getBoundary(); 00503 $this->add_message("Content-Type: ".$this->getHTMLContentType()); 00504 $this->add_message(' boundary="'.$newBoundary.'"'); 00505 $this->add_message(''); 00506 $this->constructHTML($newBoundary); 00507 } else { // Purely plain 00508 $this->add_message($this->plain_text_header); 00509 $this->add_message(''); 00510 $this->add_message($this->getContent("plain")); 00511 } 00512 // attachments are added 00513 if (is_array($this->theParts["attach"])) { 00514 reset($this->theParts["attach"]); 00515 while(list(,$media)=each($this->theParts["attach"])) { 00516 $this->add_message("--".$boundary); 00517 $this->add_message("Content-Type: ".$media["content_type"]); 00518 $this->add_message(' name="'.$media["filename"].'"'); 00519 $this->add_message("Content-Transfer-Encoding: base64"); 00520 $this->add_message("Content-Disposition: attachment;"); 00521 $this->add_message(' filename="'.$media["filename"].'"'); 00522 $this->add_message(''); 00523 $this->add_message($this->makeBase64($media["content"])); 00524 } 00525 } 00526 $this->add_message("--".$boundary."--\n"); 00527 } 00528 00535 function constructHTML ($boundary) { 00536 if (count($this->theParts["html"]["media"])) { // If media, then we know, the multipart/related content-type has been set before this function call... 00537 $this->add_message("--".$boundary); 00538 // HTML has media 00539 $newBoundary = $this->getBoundary(); 00540 $this->add_message("Content-Type: multipart/alternative;"); 00541 $this->add_message(' boundary="'.$newBoundary.'"'); 00542 $this->add_message(''); 00543 00544 $this->constructAlternative($newBoundary); // Adding the plaintext/html mix 00545 00546 $this->constructHTML_media($boundary); 00547 } else { 00548 $this->constructAlternative($boundary); // Adding the plaintext/html mix, and if no media, then use $boundary instead of $newBoundary 00549 } 00550 } 00551 00558 function constructAlternative($boundary) { 00559 // Here plain is combined with HTML 00560 $this->add_message("--".$boundary); 00561 // plain is added 00562 $this->add_message($this->plain_text_header); 00563 $this->add_message(''); 00564 $this->add_message($this->getContent("plain")); 00565 $this->add_message("--".$boundary); 00566 // html is added 00567 $this->add_message($this->html_text_header); 00568 $this->add_message(''); 00569 $this->add_message($this->getContent("html")); 00570 $this->add_message("--".$boundary."--\n"); 00571 } 00572 00579 function constructHTML_media ($boundary) { 00580 /* // Constructs the HTML-part of message if the HTML contains media 00581 $this->add_message("--".$boundary); 00582 // htmlcode is added 00583 $this->add_message($this->html_text_header); 00584 $this->add_message(''); 00585 $this->add_message($this->getContent("html")); 00586 00587 OLD stuf... 00588 00589 */ 00590 // media is added 00591 if (is_array($this->theParts["html"]["media"])) { 00592 reset($this->theParts["html"]["media"]); 00593 while(list($key,$media)=each($this->theParts["html"]["media"])) { 00594 if (!$this->mediaList || t3lib_div::inList($this->mediaList,$key)) { 00595 $this->add_message("--".$boundary); 00596 $this->add_message("Content-Type: ".$media["ctype"]); 00597 $this->add_message("Content-ID: <part".$key.".".$this->messageid.">"); 00598 $this->add_message("Content-Transfer-Encoding: base64"); 00599 $this->add_message(''); 00600 $this->add_message($this->makeBase64($media["content"])); 00601 } 00602 } 00603 } 00604 $this->add_message("--".$boundary."--\n"); 00605 } 00606 00632 function sendTheMail () { 00633 #debug(array($this->recipient,$this->subject,$this->message,$this->headers)); 00634 // Sends the mail, requires the recipient, message and headers to be set. 00635 if (trim($this->recipient) && trim($this->message)) { // && trim($this->headers) 00636 $returnPath = (strlen($this->returnPath)>0)?"-f".$this->returnPath:''; 00637 //On windows the -f flag is not used (specific for Sendmail and Postfix), but instead the php.ini parameter sendmail_from is used. 00638 if($this->returnPath) { 00639 ini_set(sendmail_from, $this->returnPath); 00640 } 00641 //If safe mode is on, the fifth parameter to mail is not allowed, so the fix wont work on unix with safe_mode=On 00642 if(!ini_get('safe_mode') && $this->forceReturnPath) { 00643 mail($this->recipient, 00644 $this->subject, 00645 $this->message, 00646 $this->headers, 00647 $returnPath); 00648 } else { 00649 mail($this->recipient, 00650 $this->subject, 00651 $this->message, 00652 $this->headers); 00653 } 00654 // Sending copy: 00655 if ($this->recipient_copy) { 00656 if(!ini_get('safe_mode') && $this->forceReturnPath) { 00657 mail( $this->recipient_copy, 00658 $this->subject, 00659 $this->message, 00660 $this->headers, 00661 $returnPath); 00662 } else { 00663 mail( $this->recipient_copy, 00664 $this->subject, 00665 $this->message, 00666 $this->headers ); 00667 } 00668 } 00669 // Auto response 00670 if ($this->auto_respond_msg) { 00671 $theParts = explode('/',$this->auto_respond_msg,2); 00672 $theParts[1] = str_replace("/",chr(10),$theParts[1]); 00673 if(!ini_get('safe_mode') && $this->forceReturnPath) { 00674 mail( $this->from_email, 00675 $theParts[0], 00676 $theParts[1], 00677 "From: ".$this->recipient, 00678 $returnPath); 00679 } else { 00680 mail( $this->from_email, 00681 $theParts[0], 00682 $theParts[1], 00683 "From: ".$this->recipient); 00684 } 00685 } 00686 if($this->returnPath) { 00687 ini_restore(sendmail_from); 00688 } 00689 return true; 00690 } else {return false;} 00691 } 00692 00698 function getBoundary() { 00699 // Returns boundaries 00700 $this->part++; 00701 return "----------".uniqid("part_".$this->part."_"); 00702 } 00703 00710 function setPlain ($content) { 00711 // Sets the plain-text part. No processing done. 00712 $this->theParts["plain"]["content"] = $content; 00713 } 00714 00721 function setHtml ($content) { 00722 // Sets the HTML-part. No processing done. 00723 $this->theParts["html"]["content"] = $content; 00724 } 00725 00732 function add_header ($header) { 00733 // Adds a header to the mail. Use this AFTER the setHeaders()-function 00734 $this->headers.=$header."\n"; 00735 } 00736 00743 function add_message ($string) { 00744 // Adds a line of text to the mail-body. Is normally use internally 00745 $this->message.=$string."\n"; 00746 } 00747 00754 function getContent($type) { 00755 return $this->theParts[$type]["content"]; 00756 } 00757 00763 function preview() { 00764 echo nl2br(HTMLSpecialChars($this->headers)); 00765 echo "<BR>"; 00766 echo nl2br(HTMLSpecialChars($this->message)); 00767 } 00768 00769 00770 00771 00772 00773 00774 00775 00776 00777 00778 00779 00780 00781 /**************************************************** 00782 * 00783 * Functions for acquiring attachments, HTML, analyzing and so on ** 00784 * 00785 ***************************************************/ 00786 00791 function fetchHTML($file) { 00792 // Fetches the HTML-content from either url og local serverfile 00793 $this->theParts["html"]["content"] = $this->getURL($file); // Fetches the content of the page 00794 if ($this->theParts["html"]["content"]) { 00795 $addr = $this->extParseUrl($file); 00796 $path = ($addr["scheme"]) ? $addr["scheme"]."://".$addr["host"].(($addr["filepath"])?$addr["filepath"]:"/") : $addr["filepath"]; 00797 $this->theParts["html"]["path"] = $path; 00798 return true; 00799 } else { 00800 return false; 00801 } 00802 } 00803 00809 function fetchHTMLMedia() { 00810 // Fetches the mediafiles which are found by extractMediaLinks() 00811 if (is_array($this->theParts["html"]["media"])) { 00812 reset ($this->theParts["html"]["media"]); 00813 if (count($this->theParts["html"]["media"]) > 0) { 00814 while (list($key,$media) = each ($this->theParts["html"]["media"])) { 00815 $picdata = $this->getExtendedURL($this->theParts["html"]["media"][$key]["absRef"]); // We fetch the content and the mime-type 00816 if (is_array($picdata)) { 00817 $this->theParts["html"]["media"][$key]["content"] = $picdata["content"]; 00818 $this->theParts["html"]["media"][$key]["ctype"] = $picdata["content_type"]; 00819 } 00820 } 00821 } 00822 } 00823 } 00824 00830 function extractMediaLinks() { 00831 // extracts all media-links from $this->theParts["html"]["content"] 00832 $html_code = $this->theParts["html"]["content"]; 00833 $attribRegex = $this->tag_regex(Array("img","table","td","tr","body","iframe","script","input","embed")); 00834 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00835 $len=strlen($codepieces[0]); 00836 $pieces = count($codepieces); 00837 for($i=1; $i < $pieces; $i++) { 00838 $tag = strtolower(strtok(substr($html_code,$len+1,10)," ")); 00839 $len+=strlen($tag)+strlen($codepieces[$i])+2; 00840 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00841 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00842 $imageData=array(); 00843 $imageData["ref"]=($attributes["src"]) ? $attributes["src"] : $attributes["background"]; // Finds the src or background attribute 00844 if ($imageData["ref"]) { 00845 $imageData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $imageData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00846 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00847 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00848 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00849 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00850 $imageData["tag"]=$tag; 00851 $imageData["use_jumpurl"]=$attributes["dmailerping"]?1:0; 00852 $this->theParts["html"]["media"][]=$imageData; 00853 } 00854 } 00855 } 00856 // Extracts stylesheets 00857 $attribRegex = $this->tag_regex(Array("link")); 00858 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00859 $pieces = count($codepieces); 00860 for($i=1; $i < $pieces; $i++) { 00861 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00862 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00863 $imageData=array(); 00864 if (strtolower($attributes["rel"])=="stylesheet" && $attributes["href"]) { 00865 $imageData["ref"]=$attributes["href"]; // Finds the src or background attribute 00866 $imageData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $imageData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00867 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00868 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00869 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00870 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00871 $this->theParts["html"]["media"][]=$imageData; 00872 } 00873 } 00874 } 00875 // fixes javascript rollovers 00876 $codepieces = split(quotemeta(".src"), $html_code); 00877 $pieces = count($codepieces); 00878 $expr = "^[^".quotemeta("\"").quotemeta("'")."]*"; 00879 for($i=1; $i < $pieces; $i++) { 00880 $temp = $codepieces[$i]; 00881 $temp = trim(ereg_replace("=","",trim($temp))); 00882 ereg ($expr,substr($temp,1,strlen($temp)),$reg); 00883 $imageData["ref"] = $reg[0]; 00884 $imageData["quotes"] = substr($temp,0,1); 00885 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00886 $theInfo = $this->split_fileref($imageData["ref"]); 00887 switch ($theInfo["fileext"]) { 00888 case "gif": 00889 case "jpeg": 00890 case "jpg": 00891 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00892 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00893 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00894 $this->theParts["html"]["media"][]=$imageData; 00895 } 00896 break; 00897 } 00898 } 00899 } 00900 00906 function extractHyperLinks() { 00907 // extracts all hyper-links from $this->theParts["html"]["content"] 00908 $html_code = $this->theParts["html"]["content"]; 00909 $attribRegex = $this->tag_regex(Array("a","form","area")); 00910 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00911 $len=strlen($codepieces[0]); 00912 $pieces = count($codepieces); 00913 for($i=1; $i < $pieces; $i++) { 00914 $tag = strtolower(strtok(substr($html_code,$len+1,10)," ")); 00915 $len+=strlen($tag)+strlen($codepieces[$i])+2; 00916 00917 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00918 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00919 $hrefData=""; 00920 if ($attributes["href"]) {$hrefData["ref"]=$attributes["href"];} else {$hrefData["ref"]=$attributes["action"];} 00921 if ($hrefData["ref"]) { 00922 $hrefData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $hrefData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00923 $hrefData["subst_str"] = $hrefData["quotes"].$hrefData["ref"].$hrefData["quotes"]; // subst_str is the string to look for, when substituting lateron 00924 if ($hrefData["ref"] && substr(trim($hrefData["ref"]),0,1)!="#" && !strstr($this->href_fullpath_list,"|".$hrefData["subst_str"]."|")) { 00925 $this->href_fullpath_list.="|".$hrefData["subst_str"]."|"; 00926 $hrefData["absRef"] = $this->absRef($hrefData["ref"]); 00927 $hrefData["tag"]=$tag; 00928 $this->theParts["html"]["hrefs"][]=$hrefData; 00929 } 00930 } 00931 } 00932 // Extracts TYPO3 specific links made by the openPic() JS function 00933 $codepieces = explode("onClick=\"openPic('", $html_code); 00934 $pieces = count($codepieces); 00935 for($i=1; $i < $pieces; $i++) { 00936 $showpic_linkArr = explode("'",$codepieces[$i]); 00937 $hrefData["ref"]=$showpic_linkArr[0]; 00938 if ($hrefData["ref"]) { 00939 $hrefData["quotes"]="'"; // Finds out if the value had quotes around it 00940 $hrefData["subst_str"] = $hrefData["quotes"].$hrefData["ref"].$hrefData["quotes"]; // subst_str is the string to look for, when substituting lateron 00941 if ($hrefData["ref"] && !strstr($this->href_fullpath_list,"|".$hrefData["subst_str"]."|")) { 00942 $this->href_fullpath_list.="|".$hrefData["subst_str"]."|"; 00943 $hrefData["absRef"] = $this->absRef($hrefData["ref"]); 00944 $this->theParts["html"]["hrefs"][]=$hrefData; 00945 } 00946 } 00947 } 00948 } 00949 00955 function extractFramesInfo() { 00956 // extracts all media-links from $this->theParts["html"]["content"] 00957 $html_code = $this->theParts["html"]["content"]; 00958 if (strpos(" ".$html_code,"<frame ")) { 00959 $attribRegex = $this->tag_regex("frame"); 00960 $codepieces = split($attribRegex, $html_code, 1000000 ); // Splits the document by the beginning of the above tags 00961 $pieces = count($codepieces); 00962 for($i=1; $i < $pieces; $i++) { 00963 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00964 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00965 $frame=""; 00966 $frame["src"]=$attributes["src"]; 00967 $frame["name"]=$attributes["name"]; 00968 $frame["absRef"] = $this->absRef($frame["src"]); 00969 $theInfo[] = $frame; 00970 } 00971 return $theInfo; 00972 } 00973 } 00974 00981 function substMediaNamesInHTML($absolute) { 00982 // This substitutes the media-references in $this->theParts["html"]["content"] 00983 // If $absolute is true, then the refs are substituted with http:// ref's indstead of Content-ID's (cid). 00984 if (is_array($this->theParts["html"]["media"])) { 00985 reset ($this->theParts["html"]["media"]); 00986 while (list($key,$val) = each ($this->theParts["html"]["media"])) { 00987 if ($val["use_jumpurl"] && $this->jumperURL_prefix) { 00988 $theSubstVal = $this->jumperURL_prefix.rawurlencode($val["absRef"]); 00989 } else { 00990 $theSubstVal = ($absolute) ? $val["absRef"] : "cid:part".$key.".".$this->messageid; 00991 } 00992 $this->theParts["html"]["content"] = str_replace( 00993 $val["subst_str"], 00994 $val["quotes"].$theSubstVal.$val["quotes"], 00995 $this->theParts["html"]["content"] ); 00996 } 00997 } 00998 if (!$absolute) { 00999 $this->fixRollOvers(); 01000 } 01001 } 01002 01008 function substHREFsInHTML() { 01009 // This substitutes the hrefs in $this->theParts["html"]["content"] 01010 if (is_array($this->theParts["html"]["hrefs"])) { 01011 reset ($this->theParts["html"]["hrefs"]); 01012 while (list($key,$val) = each ($this->theParts["html"]["hrefs"])) { 01013 if ($this->jumperURL_prefix && $val["tag"]!="form") { // Form elements cannot use jumpurl! 01014 if ($this->jumperURL_useId) { 01015 $theSubstVal = $this->jumperURL_prefix.$key; 01016 } else { 01017 $theSubstVal = $this->jumperURL_prefix.rawurlencode($val["absRef"]); 01018 } 01019 } else { 01020 $theSubstVal = $val["absRef"]; 01021 } 01022 $this->theParts["html"]["content"] = str_replace( 01023 $val["subst_str"], 01024 $val["quotes"].$theSubstVal.$val["quotes"], 01025 $this->theParts["html"]["content"] ); 01026 } 01027 } 01028 } 01029 01036 function substHTTPurlsInPlainText($content) { 01037 // This substitutes the http:// urls in plain text with links 01038 if ($this->jumperURL_prefix) { 01039 $textpieces = explode("http://", $content); 01040 $pieces = count($textpieces); 01041 $textstr = $textpieces[0]; 01042 for($i=1; $i<$pieces; $i++) { 01043 $len=strcspn($textpieces[$i],chr(32).chr(9).chr(13).chr(10)); 01044 if (trim(substr($textstr,-1))=="" && $len) { 01045 $lastChar=substr($textpieces[$i],$len-1,1); 01046 if (!ereg("[A-Za-z0-9\/#]",$lastChar)) {$len--;} // Included "\/" 3/12 01047 01048 $parts[0]="http://".substr($textpieces[$i],0,$len); 01049 $parts[1]=substr($textpieces[$i],$len); 01050 01051 if ($this->jumperURL_useId) { 01052 $this->theParts["plain"]["link_ids"][$i]=$parts[0]; 01053 $parts[0] = $this->jumperURL_prefix."-".$i; 01054 } else { 01055 $parts[0] = $this->jumperURL_prefix.rawurlencode($parts[0]); 01056 } 01057 // debug($parts); 01058 $textstr.=$parts[0].$parts[1]; 01059 } else { 01060 $textstr.='http://'.$textpieces[$i]; 01061 } 01062 } 01063 $content = $textstr; 01064 // debug(array($textstr)); 01065 // debug(md5($textstr)); 01066 // debug(md5($content)); 01067 } 01068 return $content; 01069 } 01070 01076 function fixRollOvers() { 01077 // 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!!) 01078 $theNewContent = ""; 01079 $theSplit = explode(".src",$this->theParts["html"]["content"]); 01080 if (count($theSplit)>1) { 01081 while(list($key,$part)=each($theSplit)) { 01082 $sub = substr($part,0,200); 01083 if (ereg("cid:part[^ \"']*",$sub,$reg)) { 01084 $thePos = strpos($part,$reg[0]); // The position of the string 01085 ereg("cid:part([^\.]*).*",$sub,$reg2); // Finds the id of the media... 01086 $theSubStr = $this->theParts["html"]["media"][intval($reg2[1])]["absRef"]; 01087 if ($thePos && $theSubStr) { // ... and substitutes the javaScript rollover image with this instead 01088 if (!strpos(" ".$theSubStr,"http://")) {$theSubStr = "http://";} // If the path is NOT and url, the reference is set to nothing 01089 $part = substr($part,0,$thePos).$theSubStr.substr($part,$thePos+strlen($reg[0]),strlen($part)); 01090 } 01091 } 01092 $theNewContent.= $part.((($key+1)!=count($theSplit))? ".src" : "" ); 01093 } 01094 $this->theParts["html"]["content"]=$theNewContent; 01095 } 01096 } 01097 01098 01099 01100 01101 01102 01103 01104 01105 01106 01107 01108 01109 01110 01111 01112 01113 /******************************************* 01114 * 01115 * File and URL-functions 01116 * 01117 *******************************************/ 01118 01123 function makeBase64($inputstr) { 01124 // Returns base64-encoded content, which is broken every 76 character 01125 return chunk_split(base64_encode($inputstr)); 01126 } 01127 01134 function getExtendedURL($url) { 01135 // reads the URL or file and determines the Content-type by either guessing or opening a connection to the host 01136 $res["content"] = $this->getURL($url); 01137 if (!$res["content"]) {return false;} 01138 $pathInfo = parse_url($url); 01139 $fileInfo = $this->split_fileref($pathInfo["path"]); 01140 if ($fileInfo["fileext"] == "gif") {$res["content_type"] = "image/gif";} 01141 if ($fileInfo["fileext"] == "jpg" || $fileInfo["fileext"] == "jpeg") {$res["content_type"] = "image/jpeg";} 01142 if ($fileInfo["fileext"] == "html" || $fileInfo["fileext"] == "htm") {$res["content_type"] = "text/html";} 01143 if ($fileInfo["fileext"] == "swf") {$res["content_type"] = "application/x-shockwave-flash";} 01144 if (!$res["content_type"]) {$res["content_type"] = $this->getMimeType($url);} 01145 return $res; 01146 } 01147 01154 function addUserPass($url) { 01155 $user=$this->http_username; 01156 $pass=$this->http_password; 01157 if ($user && $pass && substr($url,0,7)=="http://") { 01158 $url = "http://".$user.":".$pass."@".substr($url,7); 01159 } 01160 return $url; 01161 } 01162 01169 function getURL($url) { 01170 $url = $this->addUserPass($url); 01171 // reads a url or file 01172 if($fd = @fopen($url,"rb")) { 01173 $content = ""; 01174 while (!feof($fd)) { 01175 $content.=fread( $fd, 5000 ); 01176 } 01177 fclose( $fd ); 01178 return $content; 01179 } else { 01180 return false; 01181 } 01182 } 01183 01190 function getStrippedURL($url) { 01191 // 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 01192 if($fd = fopen($url,"rb")) { 01193 $content = ""; 01194 while (!feof($fd)) { 01195 $line = fgetss($fd, 5000); 01196 if (trim($line)) { 01197 $content.=trim($line)."\n"; 01198 } 01199 } 01200 fclose( $fd ); 01201 return $content; 01202 } 01203 } 01204 01211 function getMimeType($url) { 01212 // Opens a connection to the server and returns the mime-type of the file 01213 // takes url only 01214 $pathInfo = parse_url($url); 01215 if (!$pathInfo["scheme"]) {return false;} 01216 $getAdr = ($pathInfo["query"])?$pathInfo["path"]."?".$pathInfo["query"]:$pathInfo["path"]; 01217 $fp = fsockopen($pathInfo["host"], 80, $errno, $errstr); 01218 if(!$fp) { 01219 return false; 01220 } else { 01221 fputs($fp,"GET ".$getAdr." HTTP/1.0\n\n"); 01222 while(!feof($fp)) { 01223 $thePortion= fgets($fp,128); 01224 if (eregi("(^Content-Type: )(.*)",trim($thePortion), $reg)) { 01225 $res = trim($reg[2]); 01226 break; 01227 } 01228 } 01229 fclose($fp); 01230 } 01231 return $res; 01232 } 01233 01240 function absRef($ref) { 01241 // Returns the absolute address of a link. This is based on $this->theParts["html"]["path"] being the root-address 01242 $ref = trim($ref); 01243 $urlINFO = parse_url($ref); 01244 if ($urlINFO["scheme"]) { 01245 return $ref; 01246 } elseif (eregi("^/",$ref)){ 01247 $addr = parse_url($this->theParts["html"]["path"]); 01248 return $addr["scheme"]."://".$addr["host"].$ref; 01249 } else { 01250 return $this->theParts["html"]["path"].$ref; // If the reference is relative, the path is added, in order for us to fetch the content 01251 } 01252 } 01253 01260 function split_fileref($fileref) { 01261 // Returns an array with path, filename, filebody, fileext. 01262 if ( ereg("(.*/)(.*)$",$fileref,$reg) ) { 01263 $info["path"] = $reg[1]; 01264 $info["file"] = $reg[2]; 01265 } else { 01266 $info["path"] = ""; 01267 $info["file"] = $fileref; 01268 } 01269 $reg=""; 01270 if ( ereg("(.*)\.([^\.]*$)",$info["file"],$reg) ) { 01271 $info["filebody"] = $reg[1]; 01272 $info["fileext"] = strtolower($reg[2]); 01273 $info["realFileext"] = $reg[2]; 01274 } else { 01275 $info["filebody"] = $info["file"]; 01276 $info["fileext"] = ""; 01277 } 01278 return $info; 01279 } 01280 01287 function extParseUrl($path) { 01288 // Returns an array with file or url-information 01289 $res = parse_url($path); 01290 ereg("(.*/)([^/]*)$",$res["path"],$reg); 01291 $res["filepath"]=$reg[1]; 01292 $res["filename"]=$reg[2]; 01293 return $res; 01294 } 01295 01302 function tag_regex($tagArray) { 01303 if (!is_array($tagArray)) { 01304 $tagArray=Array($tagArray); 01305 } 01306 $theRegex = ""; 01307 $c=count($tagArray); 01308 while(list(,$tag)=each($tagArray)) { 01309 $c--; 01310 $theRegex.="<".sql_regcase($tag)."[[:space:]]".(($c)?"|":""); 01311 } 01312 return $theRegex; 01313 } 01314 01324 function get_tag_attributes($tag) { 01325 $attributes = Array(); 01326 $tag = ltrim(eregi_replace ("^<[^ ]*","",trim($tag))); 01327 $tagLen = strlen($tag); 01328 $safetyCounter = 100; 01329 // Find attribute 01330 while ($tag) { 01331 $value = ""; 01332 $reg = split("[[:space:]=>]",$tag,2); 01333 $attrib = $reg[0]; 01334 01335 $tag = ltrim(substr($tag,strlen($attrib),$tagLen)); 01336 if (substr($tag,0,1)=="=") { 01337 $tag = ltrim(substr($tag,1,$tagLen)); 01338 if (substr($tag,0,1)=='"') { // Quotes around the value 01339 $reg = explode('"',substr($tag,1,$tagLen),2); 01340 $tag = ltrim($reg[1]); 01341 $value = $reg[0]; 01342 } else { // No qoutes around value 01343 ereg("^([^[:space:]>]*)(.*)",$tag,$reg); 01344 $value = trim($reg[1]); 01345 $tag = ltrim($reg[2]); 01346 if (substr($tag,0,1)==">") { 01347 $tag =""; 01348 } 01349 } 01350 } 01351 $attributes[strtolower($attrib)]=$value; 01352 $safetyCounter--; 01353 if ($safetyCounter<0) {break;} 01354 } 01355 return $attributes; 01356 } 01357 01366 function quoted_printable($string) { 01367 return t3lib_div::quoted_printable($string, 76); 01368 } 01369 01376 function convertName($name) { 01377 if (ereg("[^".chr(32)."-".chr(60).chr(62)."-".chr(127)."]",$name)) { 01378 return '=?iso-8859-1?B?'.base64_encode($name).'?='; 01379 } else { 01380 return $name; 01381 } 01382 } 01383 } 01384 01385 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_htmlmail.php']) { 01386 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_htmlmail.php']); 01387 } 01388 ?>