Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 1999-2004 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 ***************************************************************/ 00190 class t3lib_htmlmail { 00191 // Headerinfo: 00192 var $recipient = "recipient@whatever.com"; 00193 var $recipient_copy = ""; // This recipient (or list of...) will also receive the mail. Regard it as a copy. 00194 var $subject = "This is the subject"; 00195 var $from_email = "sender@php-mailer.com"; 00196 var $from_name = "Mr. Sender"; 00197 var $replyto_email = "reply@mailer.com"; 00198 var $replyto_name = "Mr. Reply"; 00199 var $organisation = "Your Company"; 00200 var $priority = 3; // 1 = highest, 5 = lowest, 3 = normal 00201 var $mailer = "PHP mailer"; // X-mailer 00202 var $alt_base64=0; 00203 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. 00204 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 00205 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 00206 var $http_password=""; 00207 var $http_username=""; 00208 00209 00210 // Internal 00211 00212 /* This is how the $theParts-array is normally looking 00213 var $theParts = Array( 00214 "plain" => Array ( 00215 "content"=> "" 00216 ), 00217 "html" => Array ( 00218 "content"=> "", 00219 "path" => "", 00220 "media" => Array(), 00221 "hrefs" => Array() 00222 ), 00223 "attach" => Array () 00224 ); 00225 */ 00226 var $theParts = Array(); 00227 00228 var $messageid = ""; 00229 var $returnPath = ""; 00230 var $Xid = ""; 00231 00232 var $headers = ""; 00233 var $message = ""; 00234 var $part=0; 00235 var $image_fullpath_list = ""; 00236 var $href_fullpath_list = ""; 00237 00238 var $plain_text_header = "Content-Type: text/plain; charset=iso-8859-1\nContent-Transfer-Encoding: quoted-printable"; 00239 var $html_text_header = "Content-Type: text/html; charset=iso-8859-1\nContent-Transfer-Encoding: quoted-printable"; 00240 00241 00242 00243 00244 00245 00246 00247 00248 00249 00253 function start () { 00254 // Sets the message id 00255 $this->messageid = md5(microtime()).'@domain.tld'; 00256 } 00257 00263 function useBase64() { 00264 $this->plain_text_header = 'Content-Type: text/plain; charset=iso-8859-1'.chr(10).'Content-Transfer-Encoding: base64'; 00265 $this->html_text_header = 'Content-Type: text/html; charset=iso-8859-1'.chr(10).'Content-Transfer-Encoding: base64'; 00266 $this->alt_base64=1; 00267 } 00268 00275 function encodeMsg($content) { 00276 return $this->alt_base64 ? $this->makeBase64($content) : $this->quoted_printable($content); 00277 } 00278 00285 function addPlain ($content) { 00286 // Adds plain-text and qp-encodes it 00287 $content=$this->substHTTPurlsInPlainText($content); 00288 $this->setPlain($this->encodeMsg($content)); 00289 } 00290 00297 function addAttachment($file) { 00298 // Adds an attachment to the mail 00299 $theArr = $this->getExtendedURL($file); // We fetch the content and the mime-type 00300 if ($theArr) { 00301 if (!$theArr["content_type"]){$theArr["content_type"]="application/octet-stream";} 00302 $temp = $this->split_fileref($file); 00303 $theArr["filename"]= (($temp["file"])?$temp["file"]:(strpos(" ".$theArr["content_type"],"htm")?"index.html":"unknown")); 00304 $this->theParts["attach"][]=$theArr; 00305 return true; 00306 } else { return false;} 00307 } 00308 00315 function addHTML ($file) { 00316 // Adds HTML and media, encodes it from a URL or file 00317 $status = $this->fetchHTML($file); 00318 // debug(md5($status)); 00319 if (!$status) {return false;} 00320 if ($this->extractFramesInfo()) { 00321 return "Document was a frameset. Stopped"; 00322 } 00323 $this->extractMediaLinks(); 00324 $this->extractHyperLinks(); 00325 $this->fetchHTMLMedia(); 00326 $this->substMediaNamesInHTML(0); // 0 = relative 00327 $this->substHREFsInHTML(); 00328 $this->setHTML($this->encodeMsg($this->theParts["html"]["content"])); 00329 } 00330 00338 function extractHtmlInit($html,$url) { 00339 $this->theParts["html"]["content"]=$html; 00340 $this->theParts["html"]["path"]=$url; 00341 } 00342 00349 function send($recipient) { 00350 // This function sends the mail to one $recipient 00351 if ($recipient) {$this->recipient = $recipient;} 00352 $this->setHeaders(); 00353 $this->setContent(); 00354 $this->sendTheMail(); 00355 } 00356 00357 00358 00359 00360 00361 00362 00363 00364 00365 00366 00367 00368 00369 /***************************************** 00370 * 00371 * Main functions 00372 * 00373 *****************************************/ 00374 00378 function setHeaders () { 00379 // Clears the header-string and sets the headers based on object-vars. 00380 $this->headers = ""; 00381 // Message_id 00382 $this->add_header("Message-ID: <".$this->messageid.">"); 00383 // Return path 00384 if ($this->returnPath) { 00385 $this->add_header("Return-Path: ".$this->returnPath); 00386 } 00387 // X-id 00388 if ($this->Xid) { 00389 $this->add_header("X-Typo3MID: ".$this->Xid); 00390 } 00391 00392 // From 00393 if ($this->from_email) { 00394 if ($this->from_name) { 00395 $name = $this->convertName($this->from_name); 00396 $this->add_header("From: $name <$this->from_email>"); 00397 } else { 00398 $this->add_header("From: $this->from_email"); 00399 } 00400 } 00401 // Reply 00402 if ($this->replyto_email) { 00403 if ($this->replyto_name) { 00404 $name = $this->convertName($this->replyto_name); 00405 $this->add_header("Reply-To: $name <$this->replyto_email>"); 00406 } else { 00407 $this->add_header("Reply-To: $this->replyto_email"); 00408 } 00409 } 00410 // Organisation 00411 if ($this->organisation) { 00412 $name = $this->convertName($this->organisation); 00413 $this->add_header("Organisation: $name"); 00414 } 00415 // mailer 00416 if ($this->mailer) { 00417 $this->add_header("X-Mailer: $this->mailer"); 00418 } 00419 // priority 00420 if ($this->priority) { 00421 $this->add_header("X-Priority: $this->priority"); 00422 } 00423 $this->add_header("Mime-Version: 1.0"); 00424 } 00425 00432 function setRecipient ($recip) { 00433 // 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. 00434 if (is_array($recip)) { 00435 $this->recipient = ""; 00436 while (list($key,) = each($recip)) { 00437 $this->recipient .= $recip[$key].","; 00438 } 00439 $this->recipient = ereg_replace(",$","",$this->recipient); 00440 } else { 00441 $this->recipient = $recip; 00442 } 00443 } 00444 00450 function getHTMLContentType() { 00451 return count($this->theParts["html"]["media"]) ? 'multipart/related;' : 'multipart/alternative;'; 00452 } 00453 00459 function setContent() { 00460 // Begins building the message-body 00461 $this->message = ""; 00462 $boundary = $this->getBoundary(); 00463 // Setting up headers 00464 if (count($this->theParts["attach"])) { 00465 $this->add_header('Content-Type: multipart/mixed;'); 00466 $this->add_header(' boundary="'.$boundary.'"'); 00467 $this->add_message("This is a multi-part message in MIME format.\n"); 00468 $this->constructMixed($boundary); // Generate (plain/HTML) / attachments 00469 } elseif ($this->theParts["html"]["content"]) { 00470 $this->add_header('Content-Type: '.$this->getHTMLContentType()); 00471 $this->add_header(' boundary="'.$boundary.'"'); 00472 $this->add_message("This is a multi-part message in MIME format.\n"); 00473 $this->constructHTML($boundary); // Generate plain/HTML mail 00474 } else { 00475 $this->add_header($this->plain_text_header); 00476 $this->add_message($this->getContent("plain")); // Generate plain only 00477 } 00478 } 00479 00486 function constructMixed ($boundary) { 00487 // Here (plain/HTML) is combined with the attachments 00488 $this->add_message("--".$boundary); 00489 // (plain/HTML) is added 00490 if ($this->theParts["html"]["content"]) { 00491 // HTML and plain 00492 $newBoundary = $this->getBoundary(); 00493 $this->add_message("Content-Type: ".$this->getHTMLContentType()); 00494 $this->add_message(' boundary="'.$newBoundary.'"'); 00495 $this->add_message(''); 00496 $this->constructHTML($newBoundary); 00497 } else { // Purely plain 00498 $this->add_message($this->plain_text_header); 00499 $this->add_message(''); 00500 $this->add_message($this->getContent("plain")); 00501 } 00502 // attachments are added 00503 if (is_array($this->theParts["attach"])) { 00504 reset($this->theParts["attach"]); 00505 while(list(,$media)=each($this->theParts["attach"])) { 00506 $this->add_message("--".$boundary); 00507 $this->add_message("Content-Type: ".$media["content_type"]); 00508 $this->add_message(' name="'.$media["filename"].'"'); 00509 $this->add_message("Content-Transfer-Encoding: base64"); 00510 $this->add_message("Content-Disposition: attachment;"); 00511 $this->add_message(' filename="'.$media["filename"].'"'); 00512 $this->add_message(''); 00513 $this->add_message($this->makeBase64($media["content"])); 00514 } 00515 } 00516 $this->add_message("--".$boundary."--\n"); 00517 } 00518 00525 function constructHTML ($boundary) { 00526 if (count($this->theParts["html"]["media"])) { // If media, then we know, the multipart/related content-type has been set before this function call... 00527 $this->add_message("--".$boundary); 00528 // HTML has media 00529 $newBoundary = $this->getBoundary(); 00530 $this->add_message("Content-Type: multipart/alternative;"); 00531 $this->add_message(' boundary="'.$newBoundary.'"'); 00532 $this->add_message(''); 00533 00534 $this->constructAlternative($newBoundary); // Adding the plaintext/html mix 00535 00536 $this->constructHTML_media($boundary); 00537 } else { 00538 $this->constructAlternative($boundary); // Adding the plaintext/html mix, and if no media, then use $boundary instead of $newBoundary 00539 } 00540 } 00541 00548 function constructAlternative($boundary) { 00549 // Here plain is combined with HTML 00550 $this->add_message("--".$boundary); 00551 // plain is added 00552 $this->add_message($this->plain_text_header); 00553 $this->add_message(''); 00554 $this->add_message($this->getContent("plain")); 00555 $this->add_message("--".$boundary); 00556 // html is added 00557 $this->add_message($this->html_text_header); 00558 $this->add_message(''); 00559 $this->add_message($this->getContent("html")); 00560 $this->add_message("--".$boundary."--\n"); 00561 } 00562 00569 function constructHTML_media ($boundary) { 00570 /* // Constructs the HTML-part of message if the HTML contains media 00571 $this->add_message("--".$boundary); 00572 // htmlcode is added 00573 $this->add_message($this->html_text_header); 00574 $this->add_message(''); 00575 $this->add_message($this->getContent("html")); 00576 00577 OLD stuf... 00578 00579 */ 00580 // media is added 00581 if (is_array($this->theParts["html"]["media"])) { 00582 reset($this->theParts["html"]["media"]); 00583 while(list($key,$media)=each($this->theParts["html"]["media"])) { 00584 if (!$this->mediaList || t3lib_div::inList($this->mediaList,$key)) { 00585 $this->add_message("--".$boundary); 00586 $this->add_message("Content-Type: ".$media["ctype"]); 00587 $this->add_message("Content-ID: <part".$key.".".$this->messageid.">"); 00588 $this->add_message("Content-Transfer-Encoding: base64"); 00589 $this->add_message(''); 00590 $this->add_message($this->makeBase64($media["content"])); 00591 } 00592 } 00593 } 00594 $this->add_message("--".$boundary."--\n"); 00595 } 00596 00602 function sendTheMail () { 00603 // Sends the mail. 00604 // Requires the recipient, message and headers to be set. 00605 #debug(array($this->recipient,$this->subject,$this->message,$this->headers)); 00606 if (trim($this->recipient) && trim($this->message)) { // && trim($this->headers) 00607 $returnPath = (strlen($this->returnPath)>0)?"-f".$this->returnPath:''; 00608 //On windows the -f flag is not used (specific for sendmail and postfix), but instead the php.ini parameter sendmail_from is used. 00609 if($this->returnPath) { 00610 ini_set(sendmail_from, $this->returnPath); 00611 } 00612 //If safe mode is on, the fifth parameter to mail is not allowed, so the fix wont work on unix with safe_mode=On 00613 if(!ini_get('safe_mode')) { 00614 mail( $this->recipient, 00615 $this->subject, 00616 $this->message, 00617 $this->headers, 00618 $returnPath); 00619 } 00620 else { 00621 mail( $this->recipient, 00622 $this->subject, 00623 $this->message, 00624 $this->headers); 00625 } 00626 // Sending copy: 00627 if ($this->recipient_copy) { 00628 if(!ini_get('safe_mode')) { 00629 mail( $this->recipient_copy, 00630 $this->subject, 00631 $this->message, 00632 $this->headers, 00633 $returnPath); 00634 } 00635 else { 00636 mail( $this->recipient_copy, 00637 $this->subject, 00638 $this->message, 00639 $this->headers ); 00640 } 00641 } 00642 // Auto response 00643 if ($this->auto_respond_msg) { 00644 $theParts = explode("/",$this->auto_respond_msg,2); 00645 $theParts[1] = str_replace("/",chr(10),$theParts[1]); 00646 mail( $this->from_email, 00647 $theParts[0], 00648 $theParts[1], 00649 "From: ".$this->recipient, 00650 $returnPath); 00651 } 00652 if($this->returnPath) { 00653 ini_restore(sendmail_from); 00654 } 00655 return true; 00656 } else {return false;} 00657 } 00658 00664 function getBoundary() { 00665 // Returns boundaries 00666 $this->part++; 00667 return "----------".uniqid("part_".$this->part."_"); 00668 } 00669 00676 function setPlain ($content) { 00677 // Sets the plain-text part. No processing done. 00678 $this->theParts["plain"]["content"] = $content; 00679 } 00680 00687 function setHtml ($content) { 00688 // Sets the HTML-part. No processing done. 00689 $this->theParts["html"]["content"] = $content; 00690 } 00691 00698 function add_header ($header) { 00699 // Adds a header to the mail. Use this AFTER the setHeaders()-function 00700 $this->headers.=$header."\n"; 00701 } 00702 00709 function add_message ($string) { 00710 // Adds a line of text to the mail-body. Is normally use internally 00711 $this->message.=$string."\n"; 00712 } 00713 00720 function getContent($type) { 00721 return $this->theParts[$type]["content"]; 00722 } 00723 00729 function preview() { 00730 echo nl2br(HTMLSpecialChars($this->headers)); 00731 echo "<BR>"; 00732 echo nl2br(HTMLSpecialChars($this->message)); 00733 } 00734 00735 00736 00737 00738 00739 00740 00741 00742 00743 00744 00745 00746 00747 /**************************************************** 00748 * 00749 * Functions for acquiring attachments, HTML, analyzing and so on ** 00750 * 00751 ***************************************************/ 00752 00757 function fetchHTML($file) { 00758 // Fetches the HTML-content from either url og local serverfile 00759 $this->theParts["html"]["content"] = $this->getURL($file); // Fetches the content of the page 00760 if ($this->theParts["html"]["content"]) { 00761 $addr = $this->extParseUrl($file); 00762 $path = ($addr["scheme"]) ? $addr["scheme"]."://".$addr["host"].(($addr["filepath"])?$addr["filepath"]:"/") : $addr["filepath"]; 00763 $this->theParts["html"]["path"] = $path; 00764 return true; 00765 } else { 00766 return false; 00767 } 00768 } 00769 00775 function fetchHTMLMedia() { 00776 // Fetches the mediafiles which are found by extractMediaLinks() 00777 if (is_array($this->theParts["html"]["media"])) { 00778 reset ($this->theParts["html"]["media"]); 00779 if (count($this->theParts["html"]["media"]) > 0) { 00780 while (list($key,$media) = each ($this->theParts["html"]["media"])) { 00781 $picdata = $this->getExtendedURL($this->theParts["html"]["media"][$key]["absRef"]); // We fetch the content and the mime-type 00782 if (is_array($picdata)) { 00783 $this->theParts["html"]["media"][$key]["content"] = $picdata["content"]; 00784 $this->theParts["html"]["media"][$key]["ctype"] = $picdata["content_type"]; 00785 } 00786 } 00787 } 00788 } 00789 } 00790 00796 function extractMediaLinks() { 00797 // extracts all media-links from $this->theParts["html"]["content"] 00798 $html_code = $this->theParts["html"]["content"]; 00799 $attribRegex = $this->tag_regex(Array("img","table","td","tr","body","iframe","script","input","embed")); 00800 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00801 $len=strlen($codepieces[0]); 00802 $pieces = count($codepieces); 00803 for($i=1; $i < $pieces; $i++) { 00804 $tag = strtolower(strtok(substr($html_code,$len+1,10)," ")); 00805 $len+=strlen($tag)+strlen($codepieces[$i])+2; 00806 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00807 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00808 $imageData=array(); 00809 $imageData["ref"]=($attributes["src"]) ? $attributes["src"] : $attributes["background"]; // Finds the src or background attribute 00810 if ($imageData["ref"]) { 00811 $imageData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $imageData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00812 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00813 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00814 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00815 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00816 $imageData["tag"]=$tag; 00817 $imageData["use_jumpurl"]=$attributes["dmailerping"]?1:0; 00818 $this->theParts["html"]["media"][]=$imageData; 00819 } 00820 } 00821 } 00822 // Extracts stylesheets 00823 $attribRegex = $this->tag_regex(Array("link")); 00824 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00825 $pieces = count($codepieces); 00826 for($i=1; $i < $pieces; $i++) { 00827 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00828 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00829 $imageData=array(); 00830 if (strtolower($attributes["rel"])=="stylesheet" && $attributes["href"]) { 00831 $imageData["ref"]=$attributes["href"]; // Finds the src or background attribute 00832 $imageData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $imageData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00833 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00834 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00835 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00836 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00837 $this->theParts["html"]["media"][]=$imageData; 00838 } 00839 } 00840 } 00841 // fixes javascript rollovers 00842 $codepieces = split(quotemeta(".src"), $html_code); 00843 $pieces = count($codepieces); 00844 $expr = "^[^".quotemeta("\"").quotemeta("'")."]*"; 00845 for($i=1; $i < $pieces; $i++) { 00846 $temp = $codepieces[$i]; 00847 $temp = trim(ereg_replace("=","",trim($temp))); 00848 ereg ($expr,substr($temp,1,strlen($temp)),$reg); 00849 $imageData["ref"] = $reg[0]; 00850 $imageData["quotes"] = substr($temp,0,1); 00851 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00852 $theInfo = $this->split_fileref($imageData["ref"]); 00853 switch ($theInfo["fileext"]) { 00854 case "gif": 00855 case "jpeg": 00856 case "jpg": 00857 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00858 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00859 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00860 $this->theParts["html"]["media"][]=$imageData; 00861 } 00862 break; 00863 } 00864 } 00865 } 00866 00872 function extractHyperLinks() { 00873 // extracts all hyper-links from $this->theParts["html"]["content"] 00874 $html_code = $this->theParts["html"]["content"]; 00875 $attribRegex = $this->tag_regex(Array("a","form","area")); 00876 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00877 $len=strlen($codepieces[0]); 00878 $pieces = count($codepieces); 00879 for($i=1; $i < $pieces; $i++) { 00880 $tag = strtolower(strtok(substr($html_code,$len+1,10)," ")); 00881 $len+=strlen($tag)+strlen($codepieces[$i])+2; 00882 00883 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00884 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00885 $hrefData=""; 00886 if ($attributes["href"]) {$hrefData["ref"]=$attributes["href"];} else {$hrefData["ref"]=$attributes["action"];} 00887 if ($hrefData["ref"]) { 00888 $hrefData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $hrefData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00889 $hrefData["subst_str"] = $hrefData["quotes"].$hrefData["ref"].$hrefData["quotes"]; // subst_str is the string to look for, when substituting lateron 00890 if ($hrefData["ref"] && substr(trim($hrefData["ref"]),0,1)!="#" && !strstr($this->href_fullpath_list,"|".$hrefData["subst_str"]."|")) { 00891 $this->href_fullpath_list.="|".$hrefData["subst_str"]."|"; 00892 $hrefData["absRef"] = $this->absRef($hrefData["ref"]); 00893 $hrefData["tag"]=$tag; 00894 $this->theParts["html"]["hrefs"][]=$hrefData; 00895 } 00896 } 00897 } 00898 // Extracts TYPO3 specific links made by the openPic() JS function 00899 $codepieces = explode("onClick=\"openPic('", $html_code); 00900 $pieces = count($codepieces); 00901 for($i=1; $i < $pieces; $i++) { 00902 $showpic_linkArr = explode("'",$codepieces[$i]); 00903 $hrefData["ref"]=$showpic_linkArr[0]; 00904 if ($hrefData["ref"]) { 00905 $hrefData["quotes"]="'"; // Finds out if the value had quotes around it 00906 $hrefData["subst_str"] = $hrefData["quotes"].$hrefData["ref"].$hrefData["quotes"]; // subst_str is the string to look for, when substituting lateron 00907 if ($hrefData["ref"] && !strstr($this->href_fullpath_list,"|".$hrefData["subst_str"]."|")) { 00908 $this->href_fullpath_list.="|".$hrefData["subst_str"]."|"; 00909 $hrefData["absRef"] = $this->absRef($hrefData["ref"]); 00910 $this->theParts["html"]["hrefs"][]=$hrefData; 00911 } 00912 } 00913 } 00914 } 00915 00921 function extractFramesInfo() { 00922 // extracts all media-links from $this->theParts["html"]["content"] 00923 $html_code = $this->theParts["html"]["content"]; 00924 if (strpos(" ".$html_code,"<frame ")) { 00925 $attribRegex = $this->tag_regex("frame"); 00926 $codepieces = split($attribRegex, $html_code, 1000000 ); // Splits the document by the beginning of the above tags 00927 $pieces = count($codepieces); 00928 for($i=1; $i < $pieces; $i++) { 00929 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00930 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00931 $frame=""; 00932 $frame["src"]=$attributes["src"]; 00933 $frame["name"]=$attributes["name"]; 00934 $frame["absRef"] = $this->absRef($frame["src"]); 00935 $theInfo[] = $frame; 00936 } 00937 return $theInfo; 00938 } 00939 } 00940 00947 function substMediaNamesInHTML($absolute) { 00948 // This substitutes the media-references in $this->theParts["html"]["content"] 00949 // If $absolute is true, then the refs are substituted with http:// ref's indstead of Content-ID's (cid). 00950 if (is_array($this->theParts["html"]["media"])) { 00951 reset ($this->theParts["html"]["media"]); 00952 while (list($key,$val) = each ($this->theParts["html"]["media"])) { 00953 if ($val["use_jumpurl"] && $this->jumperURL_prefix) { 00954 $theSubstVal = $this->jumperURL_prefix.rawurlencode($val["absRef"]); 00955 } else { 00956 $theSubstVal = ($absolute) ? $val["absRef"] : "cid:part".$key.".".$this->messageid; 00957 } 00958 $this->theParts["html"]["content"] = str_replace( 00959 $val["subst_str"], 00960 $val["quotes"].$theSubstVal.$val["quotes"], 00961 $this->theParts["html"]["content"] ); 00962 } 00963 } 00964 if (!$absolute) { 00965 $this->fixRollOvers(); 00966 } 00967 } 00968 00974 function substHREFsInHTML() { 00975 // This substitutes the hrefs in $this->theParts["html"]["content"] 00976 if (is_array($this->theParts["html"]["hrefs"])) { 00977 reset ($this->theParts["html"]["hrefs"]); 00978 while (list($key,$val) = each ($this->theParts["html"]["hrefs"])) { 00979 if ($this->jumperURL_prefix && $val["tag"]!="form") { // Form elements cannot use jumpurl! 00980 if ($this->jumperURL_useId) { 00981 $theSubstVal = $this->jumperURL_prefix.$key; 00982 } else { 00983 $theSubstVal = $this->jumperURL_prefix.rawurlencode($val["absRef"]); 00984 } 00985 } else { 00986 $theSubstVal = $val["absRef"]; 00987 } 00988 $this->theParts["html"]["content"] = str_replace( 00989 $val["subst_str"], 00990 $val["quotes"].$theSubstVal.$val["quotes"], 00991 $this->theParts["html"]["content"] ); 00992 } 00993 } 00994 } 00995 01002 function substHTTPurlsInPlainText($content) { 01003 // This substitutes the http:// urls in plain text with links 01004 if ($this->jumperURL_prefix) { 01005 $textpieces = explode("http://", $content); 01006 $pieces = count($textpieces); 01007 $textstr = $textpieces[0]; 01008 for($i=1; $i<$pieces; $i++) { 01009 $len=strcspn($textpieces[$i],chr(32).chr(9).chr(13).chr(10)); 01010 if (trim(substr($textstr,-1))=="" && $len) { 01011 $lastChar=substr($textpieces[$i],$len-1,1); 01012 if (!ereg("[A-Za-z0-9\/#]",$lastChar)) {$len--;} // Included "\/" 3/12 01013 01014 $parts[0]="http://".substr($textpieces[$i],0,$len); 01015 $parts[1]=substr($textpieces[$i],$len); 01016 01017 if ($this->jumperURL_useId) { 01018 $this->theParts["plain"]["link_ids"][$i]=$parts[0]; 01019 $parts[0] = $this->jumperURL_prefix."-".$i; 01020 } else { 01021 $parts[0] = $this->jumperURL_prefix.rawurlencode($parts[0]); 01022 } 01023 // debug($parts); 01024 $textstr.=$parts[0].$parts[1]; 01025 } else { 01026 $textstr.='http://'.$textpieces[$i]; 01027 } 01028 } 01029 $content = $textstr; 01030 // debug(array($textstr)); 01031 // debug(md5($textstr)); 01032 // debug(md5($content)); 01033 } 01034 return $content; 01035 } 01036 01042 function fixRollOvers() { 01043 // 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!!) 01044 $theNewContent = ""; 01045 $theSplit = explode(".src",$this->theParts["html"]["content"]); 01046 if (count($theSplit)>1) { 01047 while(list($key,$part)=each($theSplit)) { 01048 $sub = substr($part,0,200); 01049 if (ereg("cid:part[^ \"']*",$sub,$reg)) { 01050 $thePos = strpos($part,$reg[0]); // The position of the string 01051 ereg("cid:part([^\.]*).*",$sub,$reg2); // Finds the id of the media... 01052 $theSubStr = $this->theParts["html"]["media"][intval($reg2[1])]["absRef"]; 01053 if ($thePos && $theSubStr) { // ... and substitutes the javaScript rollover image with this instead 01054 if (!strpos(" ".$theSubStr,"http://")) {$theSubStr = "http://";} // If the path is NOT and url, the reference is set to nothing 01055 $part = substr($part,0,$thePos).$theSubStr.substr($part,$thePos+strlen($reg[0]),strlen($part)); 01056 } 01057 } 01058 $theNewContent.= $part.((($key+1)!=count($theSplit))? ".src" : "" ); 01059 } 01060 $this->theParts["html"]["content"]=$theNewContent; 01061 } 01062 } 01063 01064 01065 01066 01067 01068 01069 01070 01071 01072 01073 01074 01075 01076 01077 01078 01079 /******************************************* 01080 * 01081 * File and URL-functions 01082 * 01083 *******************************************/ 01084 01089 function makeBase64($inputstr) { 01090 // Returns base64-encoded content, which is broken every 76 character 01091 return chunk_split(base64_encode($inputstr)); 01092 } 01093 01100 function getExtendedURL($url) { 01101 // reads the URL or file and determines the Content-type by either guessing or opening a connection to the host 01102 $res["content"] = $this->getURL($url); 01103 if (!$res["content"]) {return false;} 01104 $pathInfo = parse_url($url); 01105 $fileInfo = $this->split_fileref($pathInfo["path"]); 01106 if ($fileInfo["fileext"] == "gif") {$res["content_type"] = "image/gif";} 01107 if ($fileInfo["fileext"] == "jpg" || $fileInfo["fileext"] == "jpeg") {$res["content_type"] = "image/jpeg";} 01108 if ($fileInfo["fileext"] == "html" || $fileInfo["fileext"] == "htm") {$res["content_type"] = "text/html";} 01109 if ($fileInfo["fileext"] == "swf") {$res["content_type"] = "application/x-shockwave-flash";} 01110 if (!$res["content_type"]) {$res["content_type"] = $this->getMimeType($url);} 01111 return $res; 01112 } 01113 01120 function addUserPass($url) { 01121 $user=$this->http_username; 01122 $pass=$this->http_password; 01123 if ($user && $pass && substr($url,0,7)=="http://") { 01124 $url = "http://".$user.":".$pass."@".substr($url,7); 01125 } 01126 return $url; 01127 } 01128 01135 function getURL($url) { 01136 $url = $this->addUserPass($url); 01137 // reads a url or file 01138 if($fd = @fopen($url,"rb")) { 01139 $content = ""; 01140 while (!feof($fd)) { 01141 $content.=fread( $fd, 5000 ); 01142 } 01143 fclose( $fd ); 01144 return $content; 01145 } else { 01146 return false; 01147 } 01148 } 01149 01156 function getStrippedURL($url) { 01157 // 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 01158 if($fd = fopen($url,"rb")) { 01159 $content = ""; 01160 while (!feof($fd)) { 01161 $line = fgetss($fd, 5000); 01162 if (trim($line)) { 01163 $content.=trim($line)."\n"; 01164 } 01165 } 01166 fclose( $fd ); 01167 return $content; 01168 } 01169 } 01170 01177 function getMimeType($url) { 01178 // Opens a connection to the server and returns the mime-type of the file 01179 // takes url only 01180 $pathInfo = parse_url($url); 01181 if (!$pathInfo["scheme"]) {return false;} 01182 $getAdr = ($pathInfo["query"])?$pathInfo["path"]."?".$pathInfo["query"]:$pathInfo["path"]; 01183 $fp = fsockopen($pathInfo["host"], 80, $errno, $errstr); 01184 if(!$fp) { 01185 return false; 01186 } else { 01187 fputs($fp,"GET ".$getAdr." HTTP/1.0\n\n"); 01188 while(!feof($fp)) { 01189 $thePortion= fgets($fp,128); 01190 if (eregi("(^Content-Type: )(.*)",trim($thePortion), $reg)) { 01191 $res = trim($reg[2]); 01192 break; 01193 } 01194 } 01195 fclose($fp); 01196 } 01197 return $res; 01198 } 01199 01206 function absRef($ref) { 01207 // Returns the absolute address of a link. This is based on $this->theParts["html"]["path"] being the root-address 01208 $ref = trim($ref); 01209 $urlINFO = parse_url($ref); 01210 if ($urlINFO["scheme"]) { 01211 return $ref; 01212 } elseif (eregi("^/",$ref)){ 01213 $addr = parse_url($this->theParts["html"]["path"]); 01214 return $addr["scheme"]."://".$addr["host"].$ref; 01215 } else { 01216 return $this->theParts["html"]["path"].$ref; // If the reference is relative, the path is added, in order for us to fetch the content 01217 } 01218 } 01219 01226 function split_fileref($fileref) { 01227 // Returns an array with path, filename, filebody, fileext. 01228 if ( ereg("(.*/)(.*)$",$fileref,$reg) ) { 01229 $info["path"] = $reg[1]; 01230 $info["file"] = $reg[2]; 01231 } else { 01232 $info["path"] = ""; 01233 $info["file"] = $fileref; 01234 } 01235 $reg=""; 01236 if ( ereg("(.*)\.([^\.]*$)",$info["file"],$reg) ) { 01237 $info["filebody"] = $reg[1]; 01238 $info["fileext"] = strtolower($reg[2]); 01239 $info["realFileext"] = $reg[2]; 01240 } else { 01241 $info["filebody"] = $info["file"]; 01242 $info["fileext"] = ""; 01243 } 01244 return $info; 01245 } 01246 01253 function extParseUrl($path) { 01254 // Returns an array with file or url-information 01255 $res = parse_url($path); 01256 ereg("(.*/)([^/]*)$",$res["path"],$reg); 01257 $res["filepath"]=$reg[1]; 01258 $res["filename"]=$reg[2]; 01259 return $res; 01260 } 01261 01268 function tag_regex($tagArray) { 01269 if (!is_array($tagArray)) { 01270 $tagArray=Array($tagArray); 01271 } 01272 $theRegex = ""; 01273 $c=count($tagArray); 01274 while(list(,$tag)=each($tagArray)) { 01275 $c--; 01276 $theRegex.="<".sql_regcase($tag)."[[:space:]]".(($c)?"|":""); 01277 } 01278 return $theRegex; 01279 } 01280 01290 function get_tag_attributes($tag) { 01291 $attributes = Array(); 01292 $tag = ltrim(eregi_replace ("^<[^ ]*","",trim($tag))); 01293 $tagLen = strlen($tag); 01294 $safetyCounter = 100; 01295 // Find attribute 01296 while ($tag) { 01297 $value = ""; 01298 $reg = split("[[:space:]=>]",$tag,2); 01299 $attrib = $reg[0]; 01300 01301 $tag = ltrim(substr($tag,strlen($attrib),$tagLen)); 01302 if (substr($tag,0,1)=="=") { 01303 $tag = ltrim(substr($tag,1,$tagLen)); 01304 if (substr($tag,0,1)=='"') { // Quotes around the value 01305 $reg = explode('"',substr($tag,1,$tagLen),2); 01306 $tag = ltrim($reg[1]); 01307 $value = $reg[0]; 01308 } else { // No qoutes around value 01309 ereg("^([^[:space:]>]*)(.*)",$tag,$reg); 01310 $value = trim($reg[1]); 01311 $tag = ltrim($reg[2]); 01312 if (substr($tag,0,1)==">") { 01313 $tag =""; 01314 } 01315 } 01316 } 01317 $attributes[strtolower($attrib)]=$value; 01318 $safetyCounter--; 01319 if ($safetyCounter<0) {break;} 01320 } 01321 return $attributes; 01322 } 01323 01330 function quoted_printable($string) { 01331 // This functions is buggy. It seems that in the part where the lines are breaked every 76th character, that it fails if the break happens right in a quoted_printable encode character! 01332 $newString = ""; 01333 $theLines = explode(chr(10),$string); // Break lines. Doesn't work with mac eol's which seems to be 13. But 13-10 or 10 will work 01334 while (list(,$val)=each($theLines)) { 01335 $val = ereg_replace(chr(13)."$","",$val); // removes possible character 13 at the end of line 01336 01337 $newVal = ""; 01338 $theValLen = strlen($val); 01339 $len = 0; 01340 for ($index=0;$index<$theValLen;$index++) { 01341 $char = substr($val,$index,1); 01342 $ordVal =Ord($char); 01343 if ($len>(76-4) || ($len>(66-4)&&$ordVal==32)) { 01344 $len=0; 01345 $newVal.="=".chr(13).chr(10); 01346 } 01347 if (($ordVal>=33 && $ordVal<=60) || ($ordVal>=62 && $ordVal<=126) || $ordVal==9 || $ordVal==32) { 01348 $newVal.=$char; 01349 $len++; 01350 } else { 01351 $newVal.=sprintf("=%02X",$ordVal); 01352 $len+=3; 01353 } 01354 } 01355 $newVal = ereg_replace(chr(32)."$","=20",$newVal); // replaces a possible SPACE-character at the end of a line 01356 $newVal = ereg_replace(chr(9)."$","=09",$newVal); // replaces a possible TAB-character at the end of a line 01357 $newString.=$newVal.chr(13).chr(10); 01358 } 01359 return $newString; 01360 } 01361 01368 function convertName($name) { 01369 if (ereg("[^".chr(32)."-".chr(60).chr(62)."-".chr(127)."]",$name)) { 01370 return '=?iso-8859-1?B?'.base64_encode($name).'?='; 01371 } else { 01372 return $name; 01373 } 01374 } 01375 } 01376 01377 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_htmlmail.php']) { 01378 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_htmlmail.php']); 01379 } 01380 ?>