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 = t3lib_div::getHostname(); 00273 if (!$host || $host == '127.0.0.1' || $host == 'localhost' || $host == 'localhost.localdomain') { 00274 $host = ($TYPO3_CONF_VARS['SYS']['sitename'] ? preg_replace('/[^A-Za-z0-9_\-]/', '_', $TYPO3_CONF_VARS['SYS']['sitename']) : 'localhost') . '.TYPO3'; 00275 } 00276 $this->messageid = md5(microtime()) . '@' . $host; 00277 00278 // Default line break for Unix systems. 00279 $this->linebreak = chr(10); 00280 // 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. 00281 if (TYPO3_OS=='WIN') { 00282 $this->linebreak = chr(13).chr(10); 00283 } 00284 00285 if (!$this->charset) { 00286 if (is_object($GLOBALS['TSFE']) && $GLOBALS['TSFE']->renderCharset) { 00287 $this->charset = $GLOBALS['TSFE']->renderCharset; 00288 } elseif (is_object($GLOBALS['LANG']) && $GLOBALS['LANG']->charSet) { 00289 $this->charset = $GLOBALS['LANG']->charSet; 00290 } elseif ($GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']) { 00291 $this->charset = $GLOBALS['TYPO3_CONF_VARS']['BE']['forceCharset']; 00292 } else { 00293 $this->charset = $this->defaultCharset; 00294 } 00295 } 00296 00297 // Use quoted-printable headers by default 00298 $this->useQuotedPrintable(); 00299 } 00300 00306 function useQuotedPrintable() { 00307 $this->plain_text_header = 'Content-Type: text/plain; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: quoted-printable'; 00308 $this->html_text_header = 'Content-Type: text/html; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: quoted-printable'; 00309 } 00310 00316 function useBase64() { 00317 $this->plain_text_header = 'Content-Type: text/plain; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: base64'; 00318 $this->html_text_header = 'Content-Type: text/html; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: base64'; 00319 $this->alt_base64=1; 00320 } 00321 00327 function use8Bit() { 00328 $this->plain_text_header = 'Content-Type: text/plain; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: 8bit'; 00329 $this->html_text_header = 'Content-Type: text/html; charset='.$this->charset.$this->linebreak.'Content-Transfer-Encoding: 8bit'; 00330 $this->alt_8bit=1; 00331 } 00332 00339 function encodeMsg($content) { 00340 return $this->alt_base64 ? $this->makeBase64($content) : ($this->alt_8bit ? $content : t3lib_div::quoted_printable($content)); 00341 } 00342 00349 function addPlain ($content) { 00350 // Adds plain-text and qp-encodes it 00351 $content=$this->substHTTPurlsInPlainText($content); 00352 $this->setPlain($this->encodeMsg($content)); 00353 } 00354 00361 function addAttachment($file) { 00362 // Adds an attachment to the mail 00363 $theArr = $this->getExtendedURL($file); // We fetch the content and the mime-type 00364 if ($theArr) { 00365 if (!$theArr["content_type"]){$theArr["content_type"]="application/octet-stream";} 00366 $temp = $this->split_fileref($file); 00367 $theArr["filename"]= (($temp["file"])?$temp["file"]:(strpos(" ".$theArr["content_type"],"htm")?"index.html":"unknown")); 00368 $this->theParts["attach"][]=$theArr; 00369 return true; 00370 } else { return false;} 00371 } 00372 00379 function addHTML ($file) { 00380 // Adds HTML and media, encodes it from a URL or file 00381 $status = $this->fetchHTML($file); 00382 // debug(md5($status)); 00383 if (!$status) {return false;} 00384 if ($this->extractFramesInfo()) { 00385 return "Document was a frameset. Stopped"; 00386 } 00387 $this->extractMediaLinks(); 00388 $this->extractHyperLinks(); 00389 $this->fetchHTMLMedia(); 00390 $this->substMediaNamesInHTML(0); // 0 = relative 00391 $this->substHREFsInHTML(); 00392 $this->setHTML($this->encodeMsg($this->theParts["html"]["content"])); 00393 } 00394 00402 function extractHtmlInit($html,$url) { 00403 $this->theParts["html"]["content"]=$html; 00404 $this->theParts["html"]["path"]=$url; 00405 } 00406 00413 function send($recipient) { 00414 // This function sends the mail to one $recipient 00415 if ($recipient) {$this->recipient = $recipient;} 00416 $this->setHeaders(); 00417 $this->setContent(); 00418 $this->sendTheMail(); 00419 } 00420 00421 00422 00423 00424 00425 00426 00427 00428 00429 00430 00431 00432 00433 /***************************************** 00434 * 00435 * Main functions 00436 * 00437 *****************************************/ 00438 00442 function setHeaders() { 00443 // Clears the header-string and sets the headers based on object-vars. 00444 $this->headers = ""; 00445 // Message_id 00446 $this->add_header("Message-ID: <".$this->messageid.">"); 00447 // Return path 00448 if ($this->returnPath) { 00449 $this->add_header("Return-Path: ".$this->returnPath); 00450 $this->add_header("Errors-To: ".$this->returnPath); 00451 } 00452 // X-id 00453 if ($this->Xid) { 00454 $this->add_header("X-Typo3MID: ".$this->Xid); 00455 } 00456 00457 // From 00458 if ($this->from_email) { 00459 if ($this->from_name) { 00460 $this->add_header('From: '.$this->from_name.' <'.$this->from_email.'>'); 00461 } else { 00462 $this->add_header('From: '.$this->from_email); 00463 } 00464 } 00465 // Reply 00466 if ($this->replyto_email) { 00467 if ($this->replyto_name) { 00468 $this->add_header('Reply-To: '.$this->replyto_name.' <'.$this->replyto_email.'>'); 00469 } else { 00470 $this->add_header('Reply-To: '.$this->replyto_email); 00471 } 00472 } 00473 // Organisation 00474 if ($this->organisation) { 00475 $this->add_header('Organisation: '.$this->organisation); 00476 } 00477 // mailer 00478 if ($this->mailer) { 00479 $this->add_header("X-Mailer: $this->mailer"); 00480 } 00481 // priority 00482 if ($this->priority) { 00483 $this->add_header("X-Priority: $this->priority"); 00484 } 00485 $this->add_header("Mime-Version: 1.0"); 00486 00487 if (!$this->dontEncodeHeader) { 00488 $enc = $this->alt_base64 ? 'base64' : 'quoted_printable'; // Header must be ASCII, therefore only base64 or quoted_printable are allowed! 00489 // Quote recipient and subject 00490 $this->recipient = t3lib_div::encodeHeader($this->recipient,$enc,$this->charset); 00491 $this->subject = t3lib_div::encodeHeader($this->subject,$enc,$this->charset); 00492 } 00493 } 00494 00501 function setRecipient ($recip) { 00502 // 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. 00503 if (is_array($recip)) { 00504 $this->recipient = ""; 00505 while (list($key,) = each($recip)) { 00506 $this->recipient .= $recip[$key].","; 00507 } 00508 $this->recipient = ereg_replace(",$","",$this->recipient); 00509 } else { 00510 $this->recipient = $recip; 00511 } 00512 } 00513 00519 function getHTMLContentType() { 00520 return count($this->theParts["html"]["media"]) ? 'multipart/related;' : 'multipart/alternative;'; 00521 } 00522 00528 function setContent() { 00529 // Begins building the message-body 00530 $this->message = ""; 00531 $boundary = $this->getBoundary(); 00532 // Setting up headers 00533 if (count($this->theParts["attach"])) { 00534 $this->add_header('Content-Type: multipart/mixed;'); 00535 $this->add_header(' boundary="'.$boundary.'"'); 00536 $this->add_message("This is a multi-part message in MIME format.\n"); 00537 $this->constructMixed($boundary); // Generate (plain/HTML) / attachments 00538 } elseif ($this->theParts["html"]["content"]) { 00539 $this->add_header('Content-Type: '.$this->getHTMLContentType()); 00540 $this->add_header(' boundary="'.$boundary.'"'); 00541 $this->add_message("This is a multi-part message in MIME format.\n"); 00542 $this->constructHTML($boundary); // Generate plain/HTML mail 00543 } else { 00544 $this->add_header($this->plain_text_header); 00545 $this->add_message($this->getContent("plain")); // Generate plain only 00546 } 00547 } 00548 00555 function constructMixed ($boundary) { 00556 // Here (plain/HTML) is combined with the attachments 00557 $this->add_message("--".$boundary); 00558 // (plain/HTML) is added 00559 if ($this->theParts["html"]["content"]) { 00560 // HTML and plain 00561 $newBoundary = $this->getBoundary(); 00562 $this->add_message("Content-Type: ".$this->getHTMLContentType()); 00563 $this->add_message(' boundary="'.$newBoundary.'"'); 00564 $this->add_message(''); 00565 $this->constructHTML($newBoundary); 00566 } else { // Purely plain 00567 $this->add_message($this->plain_text_header); 00568 $this->add_message(''); 00569 $this->add_message($this->getContent("plain")); 00570 } 00571 // attachments are added 00572 if (is_array($this->theParts["attach"])) { 00573 reset($this->theParts["attach"]); 00574 while(list(,$media)=each($this->theParts["attach"])) { 00575 $this->add_message("--".$boundary); 00576 $this->add_message("Content-Type: ".$media["content_type"]); 00577 $this->add_message(' name="'.$media["filename"].'"'); 00578 $this->add_message("Content-Transfer-Encoding: base64"); 00579 $this->add_message("Content-Disposition: attachment;"); 00580 $this->add_message(' filename="'.$media["filename"].'"'); 00581 $this->add_message(''); 00582 $this->add_message($this->makeBase64($media["content"])); 00583 } 00584 } 00585 $this->add_message("--".$boundary."--\n"); 00586 } 00587 00594 function constructHTML ($boundary) { 00595 if (count($this->theParts["html"]["media"])) { // If media, then we know, the multipart/related content-type has been set before this function call... 00596 $this->add_message("--".$boundary); 00597 // HTML has media 00598 $newBoundary = $this->getBoundary(); 00599 $this->add_message("Content-Type: multipart/alternative;"); 00600 $this->add_message(' boundary="'.$newBoundary.'"'); 00601 $this->add_message('Content-Transfer-Encoding: 7bit'); 00602 $this->add_message(''); 00603 00604 $this->constructAlternative($newBoundary); // Adding the plaintext/html mix 00605 00606 $this->constructHTML_media($boundary); 00607 } else { 00608 $this->constructAlternative($boundary); // Adding the plaintext/html mix, and if no media, then use $boundary instead of $newBoundary 00609 } 00610 } 00611 00618 function constructAlternative($boundary) { 00619 // Here plain is combined with HTML 00620 $this->add_message("--".$boundary); 00621 // plain is added 00622 $this->add_message($this->plain_text_header); 00623 $this->add_message(''); 00624 $this->add_message($this->getContent("plain")); 00625 $this->add_message("--".$boundary); 00626 // html is added 00627 $this->add_message($this->html_text_header); 00628 $this->add_message(''); 00629 $this->add_message($this->getContent("html")); 00630 $this->add_message("--".$boundary."--\n"); 00631 } 00632 00639 function constructHTML_media ($boundary) { 00640 /* // Constructs the HTML-part of message if the HTML contains media 00641 $this->add_message("--".$boundary); 00642 // htmlcode is added 00643 $this->add_message($this->html_text_header); 00644 $this->add_message(''); 00645 $this->add_message($this->getContent("html")); 00646 00647 OLD stuf... 00648 00649 */ 00650 // media is added 00651 if (is_array($this->theParts["html"]["media"])) { 00652 reset($this->theParts["html"]["media"]); 00653 while(list($key,$media)=each($this->theParts["html"]["media"])) { 00654 if (!$this->mediaList || t3lib_div::inList($this->mediaList,$key)) { 00655 $this->add_message("--".$boundary); 00656 $this->add_message("Content-Type: ".$media["ctype"]); 00657 $this->add_message("Content-ID: <part".$key.".".$this->messageid.">"); 00658 $this->add_message("Content-Transfer-Encoding: base64"); 00659 $this->add_message(''); 00660 $this->add_message($this->makeBase64($media["content"])); 00661 } 00662 } 00663 } 00664 $this->add_message("--".$boundary."--\n"); 00665 } 00666 00692 function sendTheMail () { 00693 #debug(array($this->recipient,$this->subject,$this->message,$this->headers)); 00694 // Sends the mail, requires the recipient, message and headers to be set. 00695 if (trim($this->recipient) && trim($this->message)) { // && trim($this->headers) 00696 $returnPath = (strlen($this->returnPath)>0)?"-f".$this->returnPath:''; 00697 //On windows the -f flag is not used (specific for Sendmail and Postfix), but instead the php.ini parameter sendmail_from is used. 00698 if($this->returnPath) { 00699 ini_set(sendmail_from, $this->returnPath); 00700 } 00701 //If safe mode is on, the fifth parameter to mail is not allowed, so the fix wont work on unix with safe_mode=On 00702 if(!ini_get('safe_mode') && $this->forceReturnPath) { 00703 mail($this->recipient, 00704 $this->subject, 00705 $this->message, 00706 $this->headers, 00707 $returnPath); 00708 } else { 00709 mail($this->recipient, 00710 $this->subject, 00711 $this->message, 00712 $this->headers); 00713 } 00714 // Sending copy: 00715 if ($this->recipient_copy) { 00716 if(!ini_get('safe_mode') && $this->forceReturnPath) { 00717 mail( $this->recipient_copy, 00718 $this->subject, 00719 $this->message, 00720 $this->headers, 00721 $returnPath); 00722 } else { 00723 mail( $this->recipient_copy, 00724 $this->subject, 00725 $this->message, 00726 $this->headers ); 00727 } 00728 } 00729 // Auto response 00730 if ($this->auto_respond_msg) { 00731 $theParts = explode('/',$this->auto_respond_msg,2); 00732 $theParts[1] = str_replace("/",chr(10),$theParts[1]); 00733 if(!ini_get('safe_mode') && $this->forceReturnPath) { 00734 mail( $this->from_email, 00735 $theParts[0], 00736 $theParts[1], 00737 "From: ".$this->recipient, 00738 $returnPath); 00739 } else { 00740 mail( $this->from_email, 00741 $theParts[0], 00742 $theParts[1], 00743 "From: ".$this->recipient); 00744 } 00745 } 00746 if($this->returnPath) { 00747 ini_restore(sendmail_from); 00748 } 00749 return true; 00750 } else {return false;} 00751 } 00752 00758 function getBoundary() { 00759 // Returns boundaries 00760 $this->part++; 00761 return "----------".uniqid("part_".$this->part."_"); 00762 } 00763 00770 function setPlain ($content) { 00771 // Sets the plain-text part. No processing done. 00772 $this->theParts["plain"]["content"] = $content; 00773 } 00774 00781 function setHtml ($content) { 00782 // Sets the HTML-part. No processing done. 00783 $this->theParts["html"]["content"] = $content; 00784 } 00785 00792 function add_header($header) { 00793 if (!$this->dontEncodeHeader && !stristr($header,'Content-Type') && !stristr($header,'Content-Transfer-Encoding')) { 00794 // Mail headers must be ASCII, therefore we convert the whole header to either base64 or quoted_printable 00795 $parts = explode(': ',$header,2); // Field tags must not be encoded 00796 if (count($parts)==2) { 00797 $enc = $this->alt_base64 ? 'base64' : 'quoted_printable'; 00798 $parts[1] = t3lib_div::encodeHeader($parts[1],$enc,$this->charset); 00799 $header = implode(': ',$parts); 00800 } 00801 } 00802 00803 // Adds a header to the mail. Use this AFTER the setHeaders()-function 00804 $this->headers.=$header."\n"; 00805 } 00806 00813 function add_message($string) { 00814 // Adds a line of text to the mail-body. Is normally use internally 00815 $this->message.=$string."\n"; 00816 } 00817 00824 function getContent($type) { 00825 return $this->theParts[$type]["content"]; 00826 } 00827 00833 function preview() { 00834 echo nl2br(HTMLSpecialChars($this->headers)); 00835 echo "<BR>"; 00836 echo nl2br(HTMLSpecialChars($this->message)); 00837 } 00838 00839 00840 00841 00842 00843 00844 00845 00846 00847 00848 00849 00850 00851 /**************************************************** 00852 * 00853 * Functions for acquiring attachments, HTML, analyzing and so on ** 00854 * 00855 ***************************************************/ 00856 00861 function fetchHTML($file) { 00862 // Fetches the HTML-content from either url og local serverfile 00863 $this->theParts["html"]["content"] = $this->getURL($file); // Fetches the content of the page 00864 if ($this->theParts["html"]["content"]) { 00865 $addr = $this->extParseUrl($file); 00866 $path = ($addr['scheme']) ? $addr['scheme'].'://'.$addr['host'].(($addr['port'])?':'.$addr['port']:'').(($addr['filepath'])?$addr['filepath']:'/') : $addr['filepath']; 00867 $this->theParts["html"]["path"] = $path; 00868 return true; 00869 } else { 00870 return false; 00871 } 00872 } 00873 00879 function fetchHTMLMedia() { 00880 // Fetches the mediafiles which are found by extractMediaLinks() 00881 if (is_array($this->theParts["html"]["media"])) { 00882 reset ($this->theParts["html"]["media"]); 00883 if (count($this->theParts["html"]["media"]) > 0) { 00884 while (list($key,$media) = each ($this->theParts["html"]["media"])) { 00885 $picdata = $this->getExtendedURL($this->theParts["html"]["media"][$key]["absRef"]); // We fetch the content and the mime-type 00886 if (is_array($picdata)) { 00887 $this->theParts["html"]["media"][$key]["content"] = $picdata["content"]; 00888 $this->theParts["html"]["media"][$key]["ctype"] = $picdata["content_type"]; 00889 } 00890 } 00891 } 00892 } 00893 } 00894 00900 function extractMediaLinks() { 00901 // extracts all media-links from $this->theParts["html"]["content"] 00902 $html_code = $this->theParts["html"]["content"]; 00903 $attribRegex = $this->tag_regex(Array("img","table","td","tr","body","iframe","script","input","embed")); 00904 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00905 $len=strlen($codepieces[0]); 00906 $pieces = count($codepieces); 00907 $reg = array(); 00908 for($i=1; $i < $pieces; $i++) { 00909 $tag = strtolower(strtok(substr($html_code,$len+1,10)," ")); 00910 $len+=strlen($tag)+strlen($codepieces[$i])+2; 00911 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00912 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00913 $imageData=array(); 00914 $imageData["ref"]=($attributes["src"]) ? $attributes["src"] : $attributes["background"]; // Finds the src or background attribute 00915 if ($imageData["ref"]) { 00916 $imageData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $imageData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00917 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00918 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00919 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00920 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00921 $imageData["tag"]=$tag; 00922 $imageData["use_jumpurl"]=$attributes["dmailerping"]?1:0; 00923 $this->theParts["html"]["media"][]=$imageData; 00924 } 00925 } 00926 } 00927 // Extracts stylesheets 00928 $attribRegex = $this->tag_regex(Array("link")); 00929 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00930 $pieces = count($codepieces); 00931 for($i=1; $i < $pieces; $i++) { 00932 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00933 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00934 $imageData=array(); 00935 if (strtolower($attributes["rel"])=="stylesheet" && $attributes["href"]) { 00936 $imageData["ref"]=$attributes["href"]; // Finds the src or background attribute 00937 $imageData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $imageData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00938 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00939 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00940 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00941 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00942 $this->theParts["html"]["media"][]=$imageData; 00943 } 00944 } 00945 } 00946 // fixes javascript rollovers 00947 $codepieces = split(quotemeta(".src"), $html_code); 00948 $pieces = count($codepieces); 00949 $expr = "^[^".quotemeta("\"").quotemeta("'")."]*"; 00950 for($i=1; $i < $pieces; $i++) { 00951 $temp = $codepieces[$i]; 00952 $temp = trim(ereg_replace("=","",trim($temp))); 00953 ereg ($expr,substr($temp,1,strlen($temp)),$reg); 00954 $imageData["ref"] = $reg[0]; 00955 $imageData["quotes"] = substr($temp,0,1); 00956 $imageData["subst_str"] = $imageData["quotes"].$imageData["ref"].$imageData["quotes"]; // subst_str is the string to look for, when substituting lateron 00957 $theInfo = $this->split_fileref($imageData["ref"]); 00958 switch ($theInfo["fileext"]) { 00959 case "gif": 00960 case "jpeg": 00961 case "jpg": 00962 if ($imageData["ref"] && !strstr($this->image_fullpath_list,"|".$imageData["subst_str"]."|")) { 00963 $this->image_fullpath_list.="|".$imageData["subst_str"]."|"; 00964 $imageData["absRef"] = $this->absRef($imageData["ref"]); 00965 $this->theParts["html"]["media"][]=$imageData; 00966 } 00967 break; 00968 } 00969 } 00970 } 00971 00977 function extractHyperLinks() { 00978 // extracts all hyper-links from $this->theParts["html"]["content"] 00979 $html_code = $this->theParts["html"]["content"]; 00980 $attribRegex = $this->tag_regex(Array("a","form","area")); 00981 $codepieces = split($attribRegex, $html_code); // Splits the document by the beginning of the above tags 00982 $len=strlen($codepieces[0]); 00983 $pieces = count($codepieces); 00984 for($i=1; $i < $pieces; $i++) { 00985 $tag = strtolower(strtok(substr($html_code,$len+1,10)," ")); 00986 $len+=strlen($tag)+strlen($codepieces[$i])+2; 00987 00988 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 00989 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 00990 $hrefData=""; 00991 if ($attributes["href"]) {$hrefData["ref"]=$attributes["href"];} else {$hrefData["ref"]=$attributes["action"];} 00992 if ($hrefData["ref"]) { 00993 $hrefData["quotes"]=(substr($codepieces[$i],strpos($codepieces[$i], $hrefData["ref"])-1,1)=='"')?'"':''; // Finds out if the value had quotes around it 00994 $hrefData["subst_str"] = $hrefData["quotes"].$hrefData["ref"].$hrefData["quotes"]; // subst_str is the string to look for, when substituting lateron 00995 if ($hrefData["ref"] && substr(trim($hrefData["ref"]),0,1)!="#" && !strstr($this->href_fullpath_list,"|".$hrefData["subst_str"]."|")) { 00996 $this->href_fullpath_list.="|".$hrefData["subst_str"]."|"; 00997 $hrefData["absRef"] = $this->absRef($hrefData["ref"]); 00998 $hrefData["tag"]=$tag; 00999 $this->theParts["html"]["hrefs"][]=$hrefData; 01000 } 01001 } 01002 } 01003 // Extracts TYPO3 specific links made by the openPic() JS function 01004 $codepieces = explode("onClick=\"openPic('", $html_code); 01005 $pieces = count($codepieces); 01006 for($i=1; $i < $pieces; $i++) { 01007 $showpic_linkArr = explode("'",$codepieces[$i]); 01008 $hrefData["ref"]=$showpic_linkArr[0]; 01009 if ($hrefData["ref"]) { 01010 $hrefData["quotes"]="'"; // Finds out if the value had quotes around it 01011 $hrefData["subst_str"] = $hrefData["quotes"].$hrefData["ref"].$hrefData["quotes"]; // subst_str is the string to look for, when substituting lateron 01012 if ($hrefData["ref"] && !strstr($this->href_fullpath_list,"|".$hrefData["subst_str"]."|")) { 01013 $this->href_fullpath_list.="|".$hrefData["subst_str"]."|"; 01014 $hrefData["absRef"] = $this->absRef($hrefData["ref"]); 01015 $this->theParts["html"]["hrefs"][]=$hrefData; 01016 } 01017 } 01018 } 01019 } 01020 01026 function extractFramesInfo() { 01027 // extracts all media-links from $this->theParts["html"]["content"] 01028 $html_code = $this->theParts["html"]["content"]; 01029 if (strpos(" ".$html_code,"<frame ")) { 01030 $attribRegex = $this->tag_regex("frame"); 01031 $codepieces = split($attribRegex, $html_code, 1000000 ); // Splits the document by the beginning of the above tags 01032 $pieces = count($codepieces); 01033 for($i=1; $i < $pieces; $i++) { 01034 $dummy = eregi("[^>]*", $codepieces[$i], $reg); 01035 $attributes = $this->get_tag_attributes($reg[0]); // Fetches the attributes for the tag 01036 $frame=""; 01037 $frame["src"]=$attributes["src"]; 01038 $frame["name"]=$attributes["name"]; 01039 $frame["absRef"] = $this->absRef($frame["src"]); 01040 $theInfo[] = $frame; 01041 } 01042 return $theInfo; 01043 } 01044 } 01045 01052 function substMediaNamesInHTML($absolute) { 01053 // This substitutes the media-references in $this->theParts["html"]["content"] 01054 // If $absolute is true, then the refs are substituted with http:// ref's indstead of Content-ID's (cid). 01055 if (is_array($this->theParts["html"]["media"])) { 01056 reset ($this->theParts["html"]["media"]); 01057 while (list($key,$val) = each ($this->theParts["html"]["media"])) { 01058 if ($val["use_jumpurl"] && $this->jumperURL_prefix) { 01059 $theSubstVal = $this->jumperURL_prefix.t3lib_div::rawUrlEncodeFP($val['absRef']); 01060 } else { 01061 $theSubstVal = ($absolute) ? $val["absRef"] : "cid:part".$key.".".$this->messageid; 01062 } 01063 $this->theParts["html"]["content"] = str_replace( 01064 $val["subst_str"], 01065 $val["quotes"].$theSubstVal.$val["quotes"], 01066 $this->theParts["html"]["content"] ); 01067 } 01068 } 01069 if (!$absolute) { 01070 $this->fixRollOvers(); 01071 } 01072 } 01073 01079 function substHREFsInHTML() { 01080 // This substitutes the hrefs in $this->theParts["html"]["content"] 01081 if (is_array($this->theParts["html"]["hrefs"])) { 01082 reset ($this->theParts["html"]["hrefs"]); 01083 while (list($key,$val) = each ($this->theParts["html"]["hrefs"])) { 01084 if ($this->jumperURL_prefix && $val["tag"]!="form") { // Form elements cannot use jumpurl! 01085 if ($this->jumperURL_useId) { 01086 $theSubstVal = $this->jumperURL_prefix.$key; 01087 } else { 01088 $theSubstVal = $this->jumperURL_prefix.t3lib_div::rawUrlEncodeFP($val['absRef']); 01089 } 01090 } else { 01091 $theSubstVal = $val["absRef"]; 01092 } 01093 $this->theParts["html"]["content"] = str_replace( 01094 $val["subst_str"], 01095 $val["quotes"].$theSubstVal.$val["quotes"], 01096 $this->theParts["html"]["content"] ); 01097 } 01098 } 01099 } 01100 01107 function substHTTPurlsInPlainText($content) { 01108 // This substitutes the http:// urls in plain text with links 01109 if ($this->jumperURL_prefix) { 01110 $textpieces = explode("http://", $content); 01111 $pieces = count($textpieces); 01112 $textstr = $textpieces[0]; 01113 for($i=1; $i<$pieces; $i++) { 01114 $len=strcspn($textpieces[$i],chr(32).chr(9).chr(13).chr(10)); 01115 if (trim(substr($textstr,-1))=="" && $len) { 01116 $lastChar=substr($textpieces[$i],$len-1,1); 01117 if (!ereg("[A-Za-z0-9\/#]",$lastChar)) {$len--;} // Included "\/" 3/12 01118 01119 $parts[0]="http://".substr($textpieces[$i],0,$len); 01120 $parts[1]=substr($textpieces[$i],$len); 01121 01122 if ($this->jumperURL_useId) { 01123 $this->theParts["plain"]["link_ids"][$i]=$parts[0]; 01124 $parts[0] = $this->jumperURL_prefix."-".$i; 01125 } else { 01126 $parts[0] = $this->jumperURL_prefix.t3lib_div::rawUrlEncodeFP($parts[0]); 01127 } 01128 $textstr.=$parts[0].$parts[1]; 01129 } else { 01130 $textstr.='http://'.$textpieces[$i]; 01131 } 01132 } 01133 $content = $textstr; 01134 } 01135 return $content; 01136 } 01137 01143 function fixRollOvers() { 01144 // 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!!) 01145 $theNewContent = ""; 01146 $theSplit = explode(".src",$this->theParts["html"]["content"]); 01147 if (count($theSplit)>1) { 01148 while(list($key,$part)=each($theSplit)) { 01149 $sub = substr($part,0,200); 01150 if (ereg("cid:part[^ \"']*",$sub,$reg)) { 01151 $thePos = strpos($part,$reg[0]); // The position of the string 01152 ereg("cid:part([^\.]*).*",$sub,$reg2); // Finds the id of the media... 01153 $theSubStr = $this->theParts["html"]["media"][intval($reg2[1])]["absRef"]; 01154 if ($thePos && $theSubStr) { // ... and substitutes the javaScript rollover image with this instead 01155 if (!strpos(" ".$theSubStr,"http://")) {$theSubStr = "http://";} // If the path is NOT and url, the reference is set to nothing 01156 $part = substr($part,0,$thePos).$theSubStr.substr($part,$thePos+strlen($reg[0]),strlen($part)); 01157 } 01158 } 01159 $theNewContent.= $part.((($key+1)!=count($theSplit))? ".src" : "" ); 01160 } 01161 $this->theParts["html"]["content"]=$theNewContent; 01162 } 01163 } 01164 01165 01166 01167 01168 01169 01170 01171 01172 01173 01174 01175 01176 01177 01178 01179 01180 /******************************************* 01181 * 01182 * File and URL-functions 01183 * 01184 *******************************************/ 01185 01190 function makeBase64($inputstr) { 01191 // Returns base64-encoded content, which is broken every 76 character 01192 return chunk_split(base64_encode($inputstr)); 01193 } 01194 01201 function getExtendedURL($url) { 01202 // reads the URL or file and determines the Content-type by either guessing or opening a connection to the host 01203 $res["content"] = $this->getURL($url); 01204 if (!$res["content"]) {return false;} 01205 $pathInfo = parse_url($url); 01206 $fileInfo = $this->split_fileref($pathInfo["path"]); 01207 if ($fileInfo["fileext"] == "gif") {$res["content_type"] = "image/gif";} 01208 if ($fileInfo["fileext"] == "jpg" || $fileInfo["fileext"] == "jpeg") {$res["content_type"] = "image/jpeg";} 01209 if ($fileInfo['fileext'] == 'png') {$res['content_type'] = 'image/png';} 01210 if ($fileInfo["fileext"] == "html" || $fileInfo["fileext"] == "htm") {$res["content_type"] = "text/html";} 01211 if ($fileInfo['fileext'] == 'css') {$res['content_type'] = 'text/css';} 01212 if ($fileInfo["fileext"] == "swf") {$res["content_type"] = "application/x-shockwave-flash";} 01213 if (!$res["content_type"]) {$res["content_type"] = $this->getMimeType($url);} 01214 return $res; 01215 } 01216 01223 function addUserPass($url) { 01224 $user=$this->http_username; 01225 $pass=$this->http_password; 01226 $matches = array(); 01227 if ($user && $pass && preg_match('/^(https?:\/\/)/', $url, $matches)) { 01228 $url = $matches[1].$user.':'.$pass.'@'.substr($url,strlen($matches[1])); 01229 } 01230 return $url; 01231 } 01232 01239 function getURL($url) { 01240 $url = $this->addUserPass($url); 01241 // reads a url or file 01242 return t3lib_div::getURL($url); 01243 } 01244 01251 function getStrippedURL($url) { 01252 // 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 01253 if($fd = fopen($url,"rb")) { 01254 $content = ""; 01255 while (!feof($fd)) { 01256 $line = fgetss($fd, 5000); 01257 if (trim($line)) { 01258 $content.=trim($line)."\n"; 01259 } 01260 } 01261 fclose( $fd ); 01262 return $content; 01263 } 01264 } 01265 01272 function getMimeType($url) { 01273 $mimeType = ''; 01274 $headers = trim(t3lib_div::getURL($url, 2)); 01275 if ($headers) { 01276 $matches = array(); 01277 if (preg_match('/(Content-Type:[\s]*)([a-zA-Z_0-9\/\-\.\+]*)([\s]|$)/', $headers, $matches)) { 01278 $mimeType = trim($matches[2]); 01279 } 01280 } 01281 return $mimeType; 01282 } 01283 01290 function absRef($ref) { 01291 // Returns the absolute address of a link. This is based on $this->theParts["html"]["path"] being the root-address 01292 $ref = trim($ref); 01293 $urlINFO = parse_url($ref); 01294 if ($urlINFO["scheme"]) { 01295 return $ref; 01296 } elseif (eregi("^/",$ref)){ 01297 $addr = parse_url($this->theParts["html"]["path"]); 01298 return $addr['scheme'].'://'.$addr['host'].($addr['port']?':'.$addr['port']:'').$ref; 01299 } else { 01300 return $this->theParts["html"]["path"].$ref; // If the reference is relative, the path is added, in order for us to fetch the content 01301 } 01302 } 01303 01310 function split_fileref($fileref) { 01311 // Returns an array with path, filename, filebody, fileext. 01312 if ( ereg("(.*/)(.*)$",$fileref,$reg) ) { 01313 $info["path"] = $reg[1]; 01314 $info["file"] = $reg[2]; 01315 } else { 01316 $info["path"] = ""; 01317 $info["file"] = $fileref; 01318 } 01319 $reg=""; 01320 if ( ereg("(.*)\.([^\.]*$)",$info["file"],$reg) ) { 01321 $info["filebody"] = $reg[1]; 01322 $info["fileext"] = strtolower($reg[2]); 01323 $info["realFileext"] = $reg[2]; 01324 } else { 01325 $info["filebody"] = $info["file"]; 01326 $info["fileext"] = ""; 01327 } 01328 return $info; 01329 } 01330 01337 function extParseUrl($path) { 01338 // Returns an array with file or url-information 01339 $res = parse_url($path); 01340 ereg("(.*/)([^/]*)$",$res["path"],$reg); 01341 $res["filepath"]=$reg[1]; 01342 $res["filename"]=$reg[2]; 01343 return $res; 01344 } 01345 01352 function tag_regex($tagArray) { 01353 if (!is_array($tagArray)) { 01354 $tagArray=Array($tagArray); 01355 } 01356 $theRegex = ""; 01357 $c=count($tagArray); 01358 while(list(,$tag)=each($tagArray)) { 01359 $c--; 01360 $theRegex.="<".sql_regcase($tag)."[[:space:]]".(($c)?"|":""); 01361 } 01362 return $theRegex; 01363 } 01364 01374 function get_tag_attributes($tag) { 01375 $attributes = Array(); 01376 $tag = ltrim(eregi_replace ("^<[^ ]*","",trim($tag))); 01377 $tagLen = strlen($tag); 01378 $safetyCounter = 100; 01379 // Find attribute 01380 while ($tag) { 01381 $value = ""; 01382 $reg = split("[[:space:]=>]",$tag,2); 01383 $attrib = $reg[0]; 01384 01385 $tag = ltrim(substr($tag,strlen($attrib),$tagLen)); 01386 if (substr($tag,0,1)=="=") { 01387 $tag = ltrim(substr($tag,1,$tagLen)); 01388 if (substr($tag,0,1)=='"') { // Quotes around the value 01389 $reg = explode('"',substr($tag,1,$tagLen),2); 01390 $tag = ltrim($reg[1]); 01391 $value = $reg[0]; 01392 } else { // No qoutes around value 01393 ereg("^([^[:space:]>]*)(.*)",$tag,$reg); 01394 $value = trim($reg[1]); 01395 $tag = ltrim($reg[2]); 01396 if (substr($tag,0,1)==">") { 01397 $tag =""; 01398 } 01399 } 01400 } 01401 $attributes[strtolower($attrib)]=$value; 01402 $safetyCounter--; 01403 if ($safetyCounter<0) {break;} 01404 } 01405 return $attributes; 01406 } 01407 01416 function quoted_printable($string) { 01417 return t3lib_div::quoted_printable($string, 76); 01418 } 01419 01427 function convertName($name) { 01428 return $name; 01429 } 01430 } 01431 01432 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_htmlmail.php']) { 01433 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_htmlmail.php']); 01434 } 01435 ?>