PageRenderTime 59ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/system/core/core.email.php

https://github.com/danboy/Croissierd
PHP | 1767 lines | 1251 code | 316 blank | 200 comment | 143 complexity | 36c4e287f85215641e93039f370a5180 MD5 | raw file
  1. <?php
  2. /*
  3. =====================================================
  4. ExpressionEngine - by EllisLab
  5. -----------------------------------------------------
  6. http://expressionengine.com/
  7. -----------------------------------------------------
  8. Copyright (c) 2003 - 2010 EllisLab, Inc.
  9. =====================================================
  10. THIS IS COPYRIGHTED SOFTWARE
  11. PLEASE READ THE LICENSE AGREEMENT
  12. http://expressionengine.com/docs/license.html
  13. =====================================================
  14. File: core.email.php
  15. -----------------------------------------------------
  16. Purpose: Send email
  17. =====================================================
  18. */
  19. if ( ! defined('EXT'))
  20. {
  21. exit('Invalid file request');
  22. }
  23. class EEmail {
  24. // Public variables.
  25. var $protocol = "mail"; // mail/sendmail/smtp
  26. var $mailpath = "/usr/sbin/sendmail"; // Sendmail path
  27. var $smtp_host = ""; // SMTP Server. Example: mail.earthlink.net
  28. var $smtp_user = ""; // SMTP Username
  29. var $smtp_pass = ""; // SMTP Password
  30. var $smtp_auth = false; // true/false. Does SMTP require authentication?
  31. var $smtp_port = "25"; // SMTP Port
  32. var $smtp_timeout = 5; // SMTP Timeout in seconds
  33. var $debug = false; // true/false. True displays messages, false does not
  34. var $wordwrap = false; // true/false Turns word-wrap on/off
  35. var $wrapchars = "76"; // Number of characters to wrap at.
  36. var $mailtype = "text"; // text/html Defines email formatting
  37. var $charset = "utf-8"; // Default char set: iso-8859-1 or us-ascii
  38. var $encoding = "8bit"; // Default bit depth (8bit = non-US char sets)
  39. var $multipart = "mixed"; // "mixed" (in the body) or "related" (separate)
  40. var $validate = false; // true/false. Enables email validation
  41. var $priority = "3"; // Default priority (1 - 5)
  42. var $newline = "\n"; // Default newline. "\r\n" or "\n" (Use "\r\n" to comply with RFC 822)
  43. var $crlf = "\n"; // The RFC 2045 compliant CRLF for quoted-printable is "\r\n". Apparently some servers,
  44. // even on the receiving end think they need to muck with CRLFs, so using "\n", while
  45. // distasteful, is the only one that seems to work for all environments. - Derek
  46. var $bcc_batch_mode = false; // true/false Turns on/off Bcc batch feature
  47. var $bcc_batch_tot = 250; // If bcc_batch_mode = true, sets max number of Bccs in each batch
  48. var $safe_mode = FALSE; // TRUE/FALSE - when servers are in safe mode they can't use the 5th parameter of mail()
  49. var $send_multipart = TRUE; // TRUE/FALSE - Yahoo does not like multipart alternative, so this is an override. Set to FALSE for Yahoo.
  50. //-------------------------------------------------------------------------------------------
  51. // Private variables. Do not modify
  52. var $subject = "";
  53. var $body = "";
  54. var $plaintext_body = "";
  55. var $finalbody = "";
  56. var $alt_boundary = "";
  57. var $atc_boundary = "";
  58. var $header_str = "";
  59. var $smtp_connect = "";
  60. var $useragent = "";
  61. var $replyto_flag = FALSE;
  62. var $debug_msg = array();
  63. var $recipients = array();
  64. var $cc_array = array();
  65. var $bcc_array = array();
  66. var $headers = array();
  67. var $attach_name = array();
  68. var $attach_type = array();
  69. var $attach_disp = array();
  70. var $protocols = array('mail', 'sendmail', 'smtp');
  71. var $base_charsets = array('iso-8859-1', 'us-ascii');
  72. var $bit_depths = array('7bit', '8bit');
  73. var $priorities = array('1 (Highest)', '2 (High)', '3 (Normal)', '4 (Low)', '5 (Lowest)');
  74. // END VARIABLES ----------------------------------------------------------------------------
  75. /** -------------------------------------
  76. /** Constructor
  77. /** -------------------------------------*/
  78. function EEmail($init = TRUE)
  79. {
  80. global $PREFS;
  81. if ($init != TRUE)
  82. return;
  83. $this->useragent = APP_NAME.' '.APP_VER;
  84. $this->initialize();
  85. $this->set_config_values();
  86. }
  87. /* END */
  88. /** -------------------------------------
  89. /** Set config values
  90. /** -------------------------------------*/
  91. function set_config_values()
  92. {
  93. global $PREFS;
  94. $this->protocol = ( ! in_array( $PREFS->ini('mail_protocol'), $this->protocols)) ? 'mail' : $PREFS->ini('mail_protocol');
  95. $this->charset = ($PREFS->ini('email_charset') == '') ? 'utf-8' : $PREFS->ini('email_charset');
  96. $this->smtp_host = $PREFS->ini('smtp_server');
  97. $this->smtp_user = $PREFS->ini('smtp_username');
  98. $this->smtp_pass = $PREFS->ini('smtp_password');
  99. $this->safe_mode = (@ini_get("safe_mode") == 0) ? FALSE : TRUE;
  100. $this->smtp_auth = ( ! $this->smtp_user AND ! $this->smtp_pass) ? FALSE : TRUE;
  101. $this->debug = ($PREFS->ini('email_debug') == 'y') ? TRUE : FALSE;
  102. /* -------------------------------------------
  103. /* Hidden Configuration Variables
  104. /* - email_newline => Default newline.
  105. /* - email_crlf => CRLF used in quoted-printable encoding
  106. /* -------------------------------------------*/
  107. $this->newline = ($PREFS->ini('email_newline') !== FALSE) ? $PREFS->ini('email_newline') : $this->newline;
  108. $this->crlf = ($PREFS->ini('email_crlf') !== FALSE) ? $PREFS->ini('email_crlf') : $this->crlf;
  109. }
  110. /* END */
  111. /** -------------------------------------
  112. /** Initialize Variables
  113. /** -------------------------------------*/
  114. function initialize()
  115. {
  116. $this->subject = "";
  117. $this->body = "";
  118. $this->finalbody = "";
  119. $this->header_str = "";
  120. $this->replyto_flag = FALSE;
  121. $this->recipients = array();
  122. $this->headers = array();
  123. $this->debug_msg = array();
  124. $this->add_header('User-Agent', $this->useragent);
  125. $this->add_header('Date', $this->set_date());
  126. }
  127. /* END */
  128. /** -------------------------------------
  129. /** From
  130. /** -------------------------------------*/
  131. function from($from, $name = '')
  132. {
  133. if (preg_match( '/\<(.*)\>/', $from, $match))
  134. $from = $match['1'];
  135. if ($this->validate)
  136. $this->validate_email($this->str_to_array($from));
  137. // prepare the display name
  138. if ($name != '')
  139. {
  140. $name = stripslashes($name);
  141. // only use Q encoding if there are characters that would require it
  142. if ( ! preg_match('/[\200-\377]/', $name))
  143. {
  144. // add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes
  145. $name = '"'.addcslashes($name, "\0..\37\177'\"\\").'"';
  146. }
  147. else
  148. {
  149. $name = $this->prep_q_encoding($name, TRUE);
  150. }
  151. }
  152. $this->add_header('From', $name.' <'.$from.'>');
  153. $this->add_header('Return-Path', '<'.$from.'>');
  154. }
  155. /* END */
  156. /** -------------------------------------
  157. /** Reply To
  158. /** -------------------------------------*/
  159. function reply_to($replyto, $name = '')
  160. {
  161. if (preg_match( '/\<(.*)\>/', $replyto, $match))
  162. $replyto = $match['1'];
  163. if ($this->validate)
  164. $this->validate_email($this->str_to_array($replyto));
  165. if ($name == '')
  166. {
  167. $name = $replyto;
  168. }
  169. if (substr($name, 0, 1) != '"')
  170. {
  171. $name = '"'.$name.'"';
  172. }
  173. $this->add_header('Reply-To', $name.' <'.$replyto.'>');
  174. $this->replyto_flag = TRUE;
  175. }
  176. /* END */
  177. /** -------------------------------------
  178. /** Recipients
  179. /** -------------------------------------*/
  180. function to($to)
  181. {
  182. $to = $this->str_to_array($to);
  183. $to = $this->clean_email($to);
  184. if ($this->validate)
  185. $this->validate_email($to);
  186. if ($this->get_protocol() != 'mail')
  187. $this->add_header('To', implode(", ", $to));
  188. switch ($this->get_protocol())
  189. {
  190. case 'smtp' : $this->recipients = $to;
  191. break;
  192. case 'sendmail' : $this->recipients = implode(", ", $to);
  193. break;
  194. case 'mail' : $this->recipients = implode(", ", $to);
  195. break;
  196. }
  197. }
  198. /* END */
  199. /** -------------------------------------
  200. /** Cc
  201. /** -------------------------------------*/
  202. function cc($cc)
  203. {
  204. $cc = $this->str_to_array($cc);
  205. $cc = $this->clean_email($cc);
  206. if ($this->validate)
  207. $this->validate_email($cc);
  208. $this->add_header('Cc', implode(", ", $cc));
  209. if ($this->get_protocol() == "smtp")
  210. $this->cc_array = $cc;
  211. }
  212. /* END */
  213. /** -------------------------------------
  214. /** Bcc
  215. /** -------------------------------------*/
  216. function bcc($bcc, $limit = '')
  217. {
  218. if ($limit != '' && is_numeric($limit))
  219. {
  220. $this->bcc_batch_mode = true;
  221. $this->bcc_batch_tot = $limit;
  222. }
  223. $bcc = $this->str_to_array($bcc);
  224. $bcc = $this->clean_email($bcc);
  225. if ($this->validate)
  226. $this->validate_email($bcc);
  227. if (($this->get_protocol() == "smtp") || ($this->bcc_batch_mode && count($bcc) > $this->bcc_batch_tot))
  228. $this->bcc_array = $bcc;
  229. else
  230. $this->add_header('Bcc', implode(", ", $bcc));
  231. }
  232. /* END */
  233. /** -------------------------------------
  234. /** Message subject
  235. /** -------------------------------------*/
  236. function subject($subject)
  237. {
  238. $subject = $this->prep_q_encoding($subject);
  239. $this->add_header('Subject', $subject);
  240. }
  241. /* END */
  242. /** -------------------------------------
  243. /** Message body
  244. /** -------------------------------------*/
  245. function message($body, $alt = '')
  246. {
  247. global $FNS;
  248. $body = $FNS->insert_action_ids($body);
  249. $body = rtrim(str_replace("\r", "", $body));
  250. if ($alt != '')
  251. {
  252. $alt = $FNS->insert_action_ids($alt);
  253. $alt = rtrim(str_replace("\r", "", $alt));
  254. }
  255. if ($this->wordwrap === TRUE AND $this->mailtype != 'html')
  256. $this->body = $this->word_wrap($body);
  257. else
  258. $this->body = $body;
  259. if ($this->mailtype == 'html')
  260. {
  261. $this->plaintext_body = ($alt == '') ? $this->prep_quoted_printable(stripslashes($body)) : $this->prep_quoted_printable($alt);
  262. $this->body = $this->prep_quoted_printable($body);
  263. }
  264. $this->body = stripslashes($this->body);
  265. }
  266. /* END */
  267. /** -------------------------------------
  268. /** Add header item
  269. /** -------------------------------------*/
  270. function add_header($header, $value)
  271. {
  272. $this->headers[$header] = $value;
  273. }
  274. /* END */
  275. /** -------------------------------------------
  276. /** Convert sring into an array
  277. /** -------------------------------------------*/
  278. function str_to_array($email)
  279. {
  280. if ( ! is_array($email))
  281. {
  282. if (strpos($email, ',') !== FALSE)
  283. {
  284. $email = preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY);
  285. }
  286. else
  287. {
  288. $email = trim($email);
  289. settype($email, "array");
  290. }
  291. }
  292. return $email;
  293. }
  294. /* END */
  295. /** -------------------------------------
  296. /** Set boundaries
  297. /** -------------------------------------*/
  298. function set_boundaries()
  299. {
  300. $this->alt_boundary = "B_ALT_".uniqid(''); // mulipart/alternative
  301. $this->atc_boundary = "B_ATC_".uniqid(''); // attachment boundary
  302. }
  303. /* END */
  304. /** -------------------------------------
  305. /** Set Message ID
  306. /** -------------------------------------*/
  307. function set_message_id()
  308. {
  309. $from = $this->headers['Return-Path'];
  310. $from = str_replace(">", "", $from);
  311. $from = str_replace("<", "", $from);
  312. return "<".uniqid('').strstr($from, '@').">";
  313. }
  314. /* END */
  315. /** -------------------------------------
  316. /** Get Debug value
  317. /** -------------------------------------*/
  318. function get_debug()
  319. {
  320. return $this->debug;
  321. }
  322. /* END */
  323. /** -------------------------------------
  324. /** Get protocol (mail/sendmail/smtp)
  325. /** -------------------------------------*/
  326. function get_protocol($return = true)
  327. {
  328. $this->protocol = strtolower($this->protocol);
  329. $this->protocol = ( ! in_array($this->protocol, $this->protocols)) ? 'mail' : $this->protocol;
  330. if ($return == true) return $this->protocol;
  331. }
  332. /* END */
  333. /** -------------------------------------
  334. /** Get mail encoding (7bit/8bit)
  335. /** -------------------------------------*/
  336. function get_encoding($return = true)
  337. {
  338. $this->encoding = ( ! in_array($this->encoding, $this->bit_depths)) ? '7bit' : $this->encoding;
  339. if ( ! in_array($this->charset, $this->base_charsets))
  340. $this->encoding = "8bit";
  341. if ($return == true) return $this->encoding;
  342. }
  343. /* END */
  344. /** -----------------------------------------
  345. /** Get content type (text/html/attachment)
  346. /** -----------------------------------------*/
  347. function get_content_type()
  348. {
  349. if ($this->mailtype == 'html' && count($this->attach_name) == 0)
  350. return 'html';
  351. elseif ($this->mailtype == 'html' && count($this->attach_name) > 0)
  352. return 'html-attach';
  353. elseif ($this->mailtype == 'text' && count($this->attach_name) > 0)
  354. return 'plain-attach';
  355. else return 'plain';
  356. }
  357. /* END */
  358. /** -------------------------------------
  359. /** Set RFC 822 Date
  360. /** -------------------------------------*/
  361. function set_date()
  362. {
  363. $timezone = date("Z");
  364. $operator = (substr($timezone, 0, 1) == '-') ? '-' : '+';
  365. $timezone = abs($timezone);
  366. $timezone = ($timezone/3600) * 100 + ($timezone % 3600) /60;
  367. return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone);
  368. }
  369. /* END */
  370. /** -------------------------------------
  371. /** Mime message
  372. /** -------------------------------------*/
  373. function mime_message()
  374. {
  375. return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format.";
  376. }
  377. /* END */
  378. /** -------------------------------------
  379. /** Validate Email Address
  380. /** -------------------------------------*/
  381. function validate_email($email)
  382. {
  383. global $REGX;
  384. if ( ! is_array($email))
  385. {
  386. if ($this->get_debug())
  387. $this->add_error_message("The email validation method must be passed an array.");
  388. return FALSE;
  389. }
  390. foreach ($email as $val)
  391. {
  392. if ( ! $REGX->valid_email($val))
  393. {
  394. if ($this->get_debug())
  395. $this->add_error_message("Invalid Address: ". $val);
  396. return FALSE;
  397. }
  398. }
  399. }
  400. /* END */
  401. /** -------------------------------------
  402. /** Email Validation
  403. /** -------------------------------------*/
  404. function valid_email($address)
  405. {
  406. if ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address))
  407. return false;
  408. else
  409. return true;
  410. }
  411. /* END */
  412. /** ---------------------------------------------------------
  413. /** Clean Extended Email Address: Joe Smith <joe@smith.com>
  414. /** ---------------------------------------------------------*/
  415. function clean_email($email)
  416. {
  417. if ( ! is_array($email))
  418. {
  419. if (preg_match('/\<(.*)\>/', $email, $match))
  420. return $match['1'];
  421. else
  422. return $email;
  423. }
  424. $clean_email = array();
  425. for ($i=0; $i < count($email); $i++)
  426. {
  427. if (preg_match( '/\<(.*)\>/', $email[$i], $match))
  428. $clean_email[] = $match['1'];
  429. else
  430. $clean_email[] = $email[$i];
  431. }
  432. return $clean_email;
  433. }
  434. /* END */
  435. /** ------------------------------------------------
  436. /** Strip HTML from message body
  437. /** ------------------------------------------------*/
  438. // This function provides the raw message for use
  439. // in plain-text headers of HTML-formatted emails
  440. function strip_html()
  441. {
  442. $body = ($this->plaintext_body != '') ? $this->plaintext_body : $this->body;
  443. if (preg_match('@\<body(.*)\</body\>@i', $body, $match))
  444. {
  445. $body = $match['1'];
  446. $body = substr($body, strpos($body, ">") + 1);
  447. }
  448. $body = trim(strip_tags($body));
  449. $body = preg_replace( '#<!--(.*)--\>#', "", $body);
  450. $body = str_replace("\t", "", $body);
  451. for ($i = 20; $i >= 3; $i--)
  452. {
  453. $n = "";
  454. for ($x = 1; $x <= $i; $x ++)
  455. $n .= $this->newline;
  456. $body = str_replace($n, $this->newline.$this->newline, $body);
  457. }
  458. return $this->word_wrap($body, '76');
  459. }
  460. /* END */
  461. /** -------------------------------------
  462. /** Word Wrap
  463. /** -------------------------------------*/
  464. function word_wrap($str, $charlim = '')
  465. {
  466. // Set the character limit
  467. if ($charlim == '')
  468. {
  469. $charlim = ($this->wrapchars == "") ? "76" : $this->wrapchars;
  470. }
  471. // Reduce multiple spaces
  472. $str = preg_replace("| +|", " ", $str);
  473. // Standardize newlines
  474. $str = preg_replace("/\r\n|\r/", "\n", $str);
  475. // If the current word is surrounded by {unwrap} tags we'll
  476. // strip the entire chunk and replace it with a marker.
  477. $unwrap = array();
  478. if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
  479. {
  480. for ($i = 0; $i < count($matches['0']); $i++)
  481. {
  482. $unwrap[] = $matches['1'][$i];
  483. $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
  484. }
  485. }
  486. // Use PHP's native function to do the initial wordwrap.
  487. // We set the cut flag to FALSE so that any individual words that are
  488. // too long get left alone. In the next step we'll deal with them.
  489. $str = wordwrap($str, $charlim, "\n", FALSE);
  490. // Split the string into individual lines of text and cycle through them
  491. $output = "";
  492. foreach (explode("\n", $str) as $line)
  493. {
  494. // Is the line within the allowed character count?
  495. // If so we'll join it to the output and continue
  496. if (strlen($line) <= $charlim)
  497. {
  498. $output .= $line.$this->newline;
  499. continue;
  500. }
  501. $temp = '';
  502. while((strlen($line)) > $charlim)
  503. {
  504. // If the over-length word is a URL we won't wrap it
  505. if (preg_match("!\[url.+\]|://|wwww.!", $line))
  506. {
  507. break;
  508. }
  509. // Trim the word down
  510. $temp .= substr($line, 0, $charlim-1);
  511. $line = substr($line, $charlim-1);
  512. }
  513. // If $temp contains data it means we had to split up an over-length
  514. // word into smaller chunks so we'll add it back to our current line
  515. if ($temp != '')
  516. {
  517. $output .= $temp.$this->newline.$line;
  518. }
  519. else
  520. {
  521. $output .= $line;
  522. }
  523. $output .= $this->newline;
  524. }
  525. // Put our markers back
  526. if (count($unwrap) > 0)
  527. {
  528. foreach ($unwrap as $key => $val)
  529. {
  530. $output = str_replace("{{unwrapped".$key."}}", $val, $output);
  531. }
  532. }
  533. return $output;
  534. }
  535. /* END */
  536. function prep_quoted_printable($str, $charlim = '')
  537. {
  538. // Set the character limit
  539. // Don't allow over 76, as that will make servers and MUAs barf
  540. // all over quoted-printable data
  541. if ($charlim == '' OR $charlim > '76')
  542. {
  543. $charlim = '76';
  544. }
  545. // Reduce multiple spaces
  546. $str = preg_replace("| +|", " ", $str);
  547. // Standardize newlines
  548. $str = preg_replace("/\r\n|\r/", "\n", $str);
  549. // kill nulls
  550. $str = preg_replace('/\x00+/', '', $str);
  551. // We are intentionally wrapping so mail servers will encode characters
  552. // properly and MUAs will behave, so {unwrap} must go!
  553. $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str);
  554. // Break into an array of lines
  555. $lines = preg_split("/\n/", $str);
  556. $escape = '=';
  557. $output = '';
  558. foreach ($lines as $line)
  559. {
  560. $length = strlen($line);
  561. $temp = '';
  562. // Loop through each character in the line to add soft-wrap
  563. // characters at the end of a line " =\r\n" and add the newly
  564. // processed line(s) to the output
  565. for ($i = 0; $i < $length; $i++)
  566. {
  567. // Grab the next character
  568. $char = substr($line, $i, 1);
  569. $ascii = ord($char);
  570. // Convert spaces and tabs but only if it's the end of the line
  571. if ($i == ($length - 1))
  572. {
  573. $char = ($ascii == '32' OR $ascii == '9') ? $escape.sprintf('%02s', dechex($ascii)) : $char;
  574. }
  575. // encode = signs
  576. if ($ascii == '61')
  577. {
  578. $char = $escape.strtoupper(sprintf('%02s', dechex($ascii))); // =3D
  579. }
  580. // If we're at the character limit, add the line to the output,
  581. // reset our temp variable, and keep on chuggin'
  582. if ((strlen($temp) + strlen($char)) >= $charlim)
  583. {
  584. $output .= $temp.$escape.$this->crlf;
  585. $temp = '';
  586. }
  587. // Add the character to our temporary line
  588. $temp .= $char;
  589. }
  590. // Add our completed line to the output
  591. $output .= $temp.$this->crlf;
  592. }
  593. // get rid of extra CRLF tacked onto the end
  594. $output = substr($output, 0, strlen($this->crlf) * -1);
  595. return $output;
  596. }
  597. /* END */
  598. function prep_q_encoding($str, $from = FALSE)
  599. {
  600. global $PREFS;
  601. $str = str_replace(array("\r", "\n"), array('', ''), trim($str));
  602. // Line length must not exceed 76 characters, so we adjust for
  603. // a space, 7 extra characters =??Q??=, and the charset that we will add to each line
  604. $limit = 75 - 7 - strlen($PREFS->ini('charset'));
  605. // these special characters must be converted too
  606. $convert = array('_', '=', '?');
  607. if ($from === TRUE)
  608. {
  609. $convert[] = ',';
  610. $convert[] = ';';
  611. }
  612. $output = '';
  613. $temp = '';
  614. for ($i = 0, $length = strlen($str); $i < $length; $i++)
  615. {
  616. // Grab the next character
  617. $char = substr($str, $i, 1);
  618. $ascii = ord($char);
  619. // convert ALL non-printable ASCII characters and our specials
  620. if ($ascii < 32 OR $ascii > 126 OR in_array($char, $convert))
  621. {
  622. $char = '='.dechex($ascii);
  623. }
  624. // handle regular spaces a bit more compactly than =20
  625. if ($ascii == 32)
  626. {
  627. $char = '_';
  628. }
  629. // If we're at the character limit, add the line to the output,
  630. // reset our temp variable, and keep on chuggin'
  631. if ((strlen($temp) + strlen($char)) >= $limit)
  632. {
  633. $output .= $temp.$this->crlf;
  634. $temp = '';
  635. }
  636. // Add the character to our temporary line
  637. $temp .= $char;
  638. }
  639. $str = $output.$temp;
  640. // wrap each line with the shebang, charset, and transfer encoding
  641. // the preceding space on successive lines is required for header "folding"
  642. $str = trim(str_replace($this->crlf, "\n", $str));
  643. $str = trim(preg_replace('/^(.*)$/m', ' =?'.$PREFS->ini('charset').'?Q?$1?=', $str));
  644. if ($this->get_protocol() == 'mail')
  645. {
  646. // mail() will replace any control character besides CRLF with a space
  647. // so we need to force those line endings in that case
  648. $str = trim(str_replace("\n", "\r\n", $str));
  649. }
  650. else
  651. {
  652. $str = trim(str_replace("\n", $this->crlf, $str));
  653. }
  654. return $str;
  655. }
  656. /* END */
  657. /** -------------------------------------
  658. /** Assign file attachments
  659. /** -------------------------------------*/
  660. function attach($filename, $disposition = 'attachment')
  661. {
  662. $this->attach_name[] = $filename;
  663. $this->attach_type[] = $this->mime_types(next(explode('.', basename($filename))));
  664. $this->attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters
  665. }
  666. /* END */
  667. /** -------------------------------------
  668. /** Build final headers
  669. /** -------------------------------------*/
  670. function build_headers()
  671. {
  672. $this->add_header('X-Sender', $this->clean_email($this->headers['From']));
  673. $this->add_header('X-Mailer', $this->useragent);
  674. $this->add_header('X-Priority', $this->priorities[$this->priority - 1]);
  675. $this->add_header('Message-ID', $this->set_message_id());
  676. $this->add_header('Mime-Version', '1.0');
  677. }
  678. /* END */
  679. /** -------------------------------------
  680. /** Write Headers as a string
  681. /** -------------------------------------*/
  682. function write_header_string()
  683. {
  684. if ($this->protocol == 'mail')
  685. {
  686. $this->subject = $this->headers['Subject'];
  687. unset($this->headers['Subject']);
  688. }
  689. reset($this->headers);
  690. $this->header_str = "";
  691. foreach($this->headers as $key => $val)
  692. {
  693. $val = trim($val);
  694. if ($val != "")
  695. {
  696. $this->header_str .= $key.": ".$val.$this->newline;
  697. }
  698. }
  699. if ($this->get_protocol() == 'mail')
  700. {
  701. $this->header_str = rtrim($this->header_str);
  702. }
  703. }
  704. /* END */
  705. /** -------------------------------------
  706. /** Build Final Body and attachments
  707. /** -------------------------------------*/
  708. function build_finalbody()
  709. {
  710. $this->set_boundaries();
  711. $this->write_header_string();
  712. $hdr = ($this->get_protocol() == 'mail') ? $this->newline : '';
  713. switch ($this->get_content_type())
  714. {
  715. case 'plain' :
  716. $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
  717. $hdr .= "Content-Transfer-Encoding: " . $this->get_encoding();
  718. if ($this->get_protocol() == 'mail')
  719. {
  720. $this->header_str .= $hdr;
  721. $this->finalbody = $this->body;
  722. return;
  723. }
  724. $hdr .= $this->newline . $this->newline . $this->body;
  725. $this->finalbody = $hdr;
  726. return;
  727. break;
  728. case 'html' :
  729. if ($this->send_multipart === FALSE)
  730. {
  731. $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
  732. $hdr .= "Content-Transfer-Encoding: quoted-printable";
  733. }
  734. else
  735. {
  736. $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->alt_boundary . "\"" . $this->newline . $this->newline;
  737. $hdr .= $this->mime_message() . $this->newline . $this->newline;
  738. $hdr .= "--" . $this->alt_boundary . $this->newline;
  739. $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
  740. $hdr .= "Content-Transfer-Encoding: quoted-printable" . $this->newline . $this->newline;
  741. $hdr .= $this->strip_html() . $this->newline . $this->newline . "--" . $this->alt_boundary . $this->newline;
  742. $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
  743. $hdr .= "Content-Transfer-Encoding: quoted-printable";
  744. }
  745. if ($this->get_protocol() == 'mail')
  746. {
  747. $this->header_str .= $hdr;
  748. $this->finalbody = $this->body . $this->newline . $this->newline;
  749. if ($this->send_multipart !== FALSE)
  750. {
  751. $this->finalbody .= "--" . $this->alt_boundary . "--";
  752. }
  753. return;
  754. }
  755. $hdr .= $this->newline . $this->newline;
  756. $hdr .= $this->body . $this->newline . $this->newline;
  757. if ($this->send_multipart !== FALSE)
  758. {
  759. $hdr .= "--" . $this->alt_boundary . "--";
  760. }
  761. $this->finalbody = $hdr;
  762. return;
  763. break;
  764. case 'plain-attach' :
  765. $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->atc_boundary."\"" . $this->newline . $this->newline;
  766. $hdr .= $this->mime_message() . $this->newline . $this->newline;
  767. $hdr .= "--" . $this->atc_boundary . $this->newline;
  768. $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
  769. $hdr .= "Content-Transfer-Encoding: " . $this->get_encoding();
  770. if ($this->get_protocol() == 'mail')
  771. {
  772. $this->header_str .= $hdr;
  773. $body = $this->body . $this->newline . $this->newline;
  774. }
  775. $hdr .= $this->newline . $this->newline;
  776. $hdr .= $this->body . $this->newline . $this->newline;
  777. break;
  778. case 'html-attach' :
  779. $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->atc_boundary."\"" . $this->newline . $this->newline;
  780. $hdr .= $this->mime_message() . $this->newline . $this->newline;
  781. $hdr .= "--" . $this->atc_boundary . $this->newline;
  782. $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->alt_boundary . "\"" . $this->newline .$this->newline;
  783. $hdr .= "--" . $this->alt_boundary . $this->newline;
  784. $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline;
  785. $hdr .= "Content-Transfer-Encoding: quoted-printable" . $this->newline . $this->newline;
  786. $hdr .= $this->strip_html() . $this->newline . $this->newline . "--" . $this->alt_boundary . $this->newline;
  787. $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline;
  788. $hdr .= "Content-Transfer-Encoding: quoted-printable";
  789. if ($this->get_protocol() == 'mail')
  790. {
  791. $this->header_str .= $hdr;
  792. $body = $this->body . $this->newline . $this->newline;
  793. $body .= "--" . $this->alt_boundary . "--" . $this->newline . $this->newline;
  794. }
  795. $hdr .= $this->newline . $this->newline;
  796. $hdr .= $this->body . $this->newline . $this->newline;
  797. $hdr .= "--" . $this->alt_boundary . "--" . $this->newline . $this->newline;
  798. break;
  799. }
  800. $attachment = array();
  801. $z = 0;
  802. for ($i=0; $i < count($this->attach_name); $i++)
  803. {
  804. $filename = $this->attach_name[$i];
  805. $basename = basename($filename);
  806. $ctype = $this->attach_type[$i];
  807. if (!file_exists($filename))
  808. {
  809. $this->add_error_message("Unable to locate this attachment: ".$filename);
  810. }
  811. $h = "--".$this->atc_boundary.$this->newline;
  812. $h .= "Content-type: ".$ctype."; ";
  813. $h .= "name=\"".$basename."\"".$this->newline;
  814. $h .= "Content-Disposition: ".$this->attach_disp[$i].";".$this->newline;
  815. $h .= "Content-Transfer-Encoding: base64".$this->newline;
  816. $attachment[$z++] = $h;
  817. $file = filesize($filename) +1;
  818. $fp = fopen($filename, 'r');
  819. $attachment[$z++] = chunk_split(base64_encode(fread($fp, $file)));
  820. fclose($fp);
  821. }
  822. if ($this->get_protocol() == 'mail')
  823. {
  824. $this->finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->atc_boundary."--";
  825. return;
  826. }
  827. $this->finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->atc_boundary."--";
  828. return;
  829. }
  830. /* END */
  831. /** -------------------------------------
  832. /** Send Email
  833. /** -------------------------------------*/
  834. function send()
  835. {
  836. // Was the reply-to header set?
  837. // If not we'll do it now...
  838. if ($this->replyto_flag == FALSE)
  839. {
  840. $this->reply_to($this->headers['From']);
  841. }
  842. if (( ! isset($this->recipients) AND ! isset($this->headers['To'])) AND
  843. ( ! isset($this->bcc_array) AND ! isset($this->headers['Bcc'])) AND
  844. ( ! isset($this->headers['Cc'])))
  845. {
  846. if ($this->get_debug())
  847. $this->error_message("You must include recipients: To, Cc, or Bcc");
  848. return FALSE;
  849. }
  850. $this->build_headers();
  851. if ($this->bcc_batch_mode AND count($this->bcc_array) > 0)
  852. {
  853. if (count($this->bcc_array) > $this->bcc_batch_tot)
  854. return $this->batch_bcc_send();
  855. }
  856. $this->build_finalbody();
  857. if ( ! $this->mail_spool())
  858. return false;
  859. else
  860. return true;
  861. }
  862. /* END */
  863. /** --------------------------------------------------
  864. /** Batch Bcc Send. Sends groups of Bccs in batches
  865. /** --------------------------------------------------*/
  866. function batch_bcc_send()
  867. {
  868. $float = $this->bcc_batch_tot -1;
  869. $flag = 0;
  870. $set = "";
  871. $chunk = array();
  872. for ($i = 0; $i < count($this->bcc_array); $i++)
  873. {
  874. if (isset($this->bcc_array[$i]))
  875. $set .= ", ".$this->bcc_array[$i];
  876. if ($i == $float)
  877. {
  878. $chunk[] = substr($set, 1);
  879. $float = $float + $this->bcc_batch_tot;
  880. $set = "";
  881. }
  882. if ($i == count($this->bcc_array)-1)
  883. $chunk[] = substr($set, 1);
  884. }
  885. for ($i = 0; $i < count($chunk); $i++)
  886. {
  887. unset($this->headers['Bcc']);
  888. unset($bcc);
  889. $bcc = $this->str_to_array($chunk[$i]);
  890. $bcc = $this->clean_email($bcc);
  891. if ($this->protocol != 'smtp')
  892. $this->add_header('Bcc', implode(", ", $bcc));
  893. else
  894. $this->bcc_array = $bcc;
  895. $this->build_finalbody();
  896. $this->mail_spool();
  897. }
  898. }
  899. /* END */
  900. /** -------------------------------------
  901. /** Unwrap special elements
  902. /** -------------------------------------*/
  903. function unwrap_specials()
  904. {
  905. $this->finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, 'remove_nl_callback'), $this->finalbody);
  906. }
  907. /* END */
  908. /** -------------------------------------
  909. /** Strip line-breaks via callback
  910. /** -------------------------------------*/
  911. function remove_nl_callback($matches)
  912. {
  913. return preg_replace("/(\r\n)|(\r)|(\n)/", "", $matches['1']);
  914. }
  915. /* END */
  916. /** -------------------------------------
  917. /** Spool mail to the mail server
  918. /** -------------------------------------*/
  919. function mail_spool()
  920. {
  921. $this->unwrap_specials();
  922. switch ($this->get_protocol())
  923. {
  924. case 'mail' :
  925. if ( ! $this->send_with_mail())
  926. {
  927. if ($this->get_debug())
  928. $this->add_error_message("Unable to send email using PHP mail(). Your server might not be configured to send mail using this method.");
  929. return FALSE;
  930. }
  931. break;
  932. case 'sendmail' :
  933. if ( ! $this->send_with_sendmail())
  934. {
  935. if ($this->get_debug())
  936. $this->add_error_message("Unable to send email using Sendmail");
  937. return FALSE;
  938. }
  939. break;
  940. case 'smtp' :
  941. if ( ! $this->send_with_smtp())
  942. {
  943. if ($this->get_debug())
  944. $this->add_error_message("Unable to send email using SMTP");
  945. return FALSE;
  946. }
  947. break;
  948. }
  949. $this->good_message("Your message has been successfully sent using ".$this->get_protocol());
  950. return true;
  951. }
  952. /* END */
  953. /** -------------------------------------
  954. /** Send using mail()
  955. /** -------------------------------------*/
  956. function send_with_mail()
  957. {
  958. if ($this->safe_mode == TRUE)
  959. {
  960. if ( ! mail($this->recipients, $this->subject, $this->finalbody, $this->header_str))
  961. return false;
  962. else
  963. return true;
  964. }
  965. else
  966. {
  967. if ( ! mail($this->recipients, $this->subject, $this->finalbody, $this->header_str, "-f ".$this->clean_email($this->headers['From'])))
  968. return false;
  969. else
  970. return true;
  971. }
  972. }
  973. /* END */
  974. /** -------------------------------------
  975. /** Send using Sendmail
  976. /** -------------------------------------*/
  977. function send_with_sendmail()
  978. {
  979. $fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->headers['From'])." -t", 'w');
  980. if ($fp === FALSE OR $fp === NULL)
  981. {
  982. // server probably has popen disabled, so nothing we can do to get a verbose error.
  983. return FALSE;
  984. }
  985. fputs($fp, $this->header_str);
  986. fputs($fp, $this->finalbody);
  987. $status = pclose($fp);
  988. if (version_compare(PHP_VERSION, '4.2.3') == -1)
  989. {
  990. $status = $status >> 8 & 0xFF;
  991. }
  992. if ($this->get_debug())
  993. {
  994. $this->add_error_message('Status: '.$status.'.');
  995. }
  996. if ($status != 0)
  997. {
  998. if ($this->get_debug())
  999. {
  1000. $this->add_error_message("Status: {$status} - Unable to open a socket to Sendmail. Please check settings.");
  1001. }
  1002. return FALSE;
  1003. }
  1004. return TRUE;
  1005. }
  1006. /* END */
  1007. /** -------------------------------------
  1008. /** Send using SMTP
  1009. /** -------------------------------------*/
  1010. function send_with_smtp()
  1011. {
  1012. if ($this->smtp_host == '')
  1013. {
  1014. if ($this->get_debug())
  1015. $this->add_error_message('You did not specify a SMTP hostname');
  1016. return FALSE;
  1017. }
  1018. $this->smtp_connect();
  1019. $this->smtp_authenticate();
  1020. $this->send_command('from', $this->clean_email($this->headers['From']));
  1021. foreach($this->recipients as $val)
  1022. $this->send_command('to', $val);
  1023. if (count($this->cc_array) > 0)
  1024. {
  1025. foreach($this->cc_array as $val)
  1026. {
  1027. if ($val != "")
  1028. $this->send_command('to', $val);
  1029. }
  1030. }
  1031. if (count($this->bcc_array) > 0)
  1032. {
  1033. foreach($this->bcc_array as $val)
  1034. {
  1035. if ($val != "")
  1036. $this->send_command('to', $val);
  1037. }
  1038. }
  1039. $this->send_command('data');
  1040. // $this->send_data($this->header_str . $this->newline . $this->finalbody);
  1041. // perform dot transformation on any lines that begin with a dot
  1042. $this->send_data($this->header_str . preg_replace('/^\./m', '..$1', $this->finalbody));
  1043. $this->send_data('.');
  1044. $reply = $this->get_data();
  1045. $this->good_message($reply);
  1046. if (substr($reply, 0, 3) != '250')
  1047. {
  1048. if ($this->get_debug())
  1049. $this->add_error_message('Failed to send SMTP email. Error: '.$reply);
  1050. return FALSE;
  1051. }
  1052. $this->send_command('quit');
  1053. return true;
  1054. }
  1055. /* END */
  1056. /** -------------------------------------
  1057. /** SMTP Connect
  1058. /** -------------------------------------*/
  1059. function smtp_connect()
  1060. {
  1061. $this->smtp_connect = fsockopen($this->smtp_host,
  1062. $this->smtp_port,
  1063. $errno,
  1064. $errstr,
  1065. $this->smtp_timeout);
  1066. if( ! is_resource($this->smtp_connect))
  1067. {
  1068. if ($this->get_debug())
  1069. $this->add_error_message("Unable to open SMTP socket. Error Number: ".$errno." Error Msg: ".$errstr);
  1070. return FALSE;
  1071. }
  1072. $this->good_message($this->get_data());
  1073. return $this->send_command('hello');
  1074. }
  1075. /* END */
  1076. /** -------------------------------------
  1077. /** Send SMTP command
  1078. /** -------------------------------------*/
  1079. function send_command($cmd, $data = '')
  1080. {
  1081. switch ($cmd)
  1082. {
  1083. case 'hello' :
  1084. if ($this->smtp_auth || $this->get_encoding() == '8bit')
  1085. $this->send_data('EHLO '.$this->get_hostname());
  1086. else
  1087. $this->send_data('HELO '.$this->get_hostname());
  1088. $resp = 250;
  1089. break;
  1090. case 'from' :
  1091. $this->send_data('MAIL FROM:<'.$data.'>');
  1092. $resp = 250;
  1093. break;
  1094. case 'to' :
  1095. $this->send_data('RCPT TO:<'.$data.'>');
  1096. $resp = 250;
  1097. break;
  1098. case 'data' :
  1099. $this->send_data('DATA');
  1100. $resp = 354;
  1101. break;
  1102. case 'quit' :
  1103. $this->send_data('QUIT');
  1104. $resp = 221;
  1105. break;
  1106. }
  1107. $reply = $this->get_data();
  1108. if ($this->get_debug())
  1109. $this->debug_msg[] = "<pre>".$cmd.": ".$reply."</pre>";
  1110. if (substr($reply, 0, 3) != $resp)
  1111. {
  1112. if ($this->get_debug())
  1113. $this->add_error_message('Failed to Send Command. Error: '.$reply);
  1114. return FALSE;
  1115. }
  1116. if ($cmd == 'quit')
  1117. fclose($this->smtp_connect);
  1118. return true;
  1119. }
  1120. /* END */
  1121. /** -------------------------------------
  1122. /** SMTP Authenticate
  1123. /** -------------------------------------*/
  1124. function smtp_authenticate()
  1125. {
  1126. if ( ! $this->smtp_auth)
  1127. return true;
  1128. if ($this->smtp_user == "" AND $this->smtp_pass == "")
  1129. {
  1130. if ($this->get_debug())
  1131. $this->add_error_message('Error: You must assign an SMTP username and password.');
  1132. return FALSE;
  1133. }
  1134. $this->send_data('AUTH LOGIN');
  1135. $reply = $this->get_data();
  1136. if (substr($reply, 0, 3) != '334')
  1137. {
  1138. if ($this->get_debug())
  1139. $this->add_error_message('Failed to send AUTH LOGIN command. Error: '.$reply);
  1140. return FALSE;
  1141. }
  1142. $this->send_data(base64_encode($this->smtp_user));
  1143. $reply = $this->get_data();
  1144. if (substr($reply, 0, 3) != '334')
  1145. {
  1146. if ($this->get_debug())
  1147. $this->add_error_message('Failed to authenticate username. Error: '.$reply);
  1148. return FALSE;
  1149. }
  1150. $this->send_data(base64_encode($this->smtp_pass));
  1151. $reply = $this->get_data();
  1152. if (substr($reply, 0, 3) != '235')
  1153. {
  1154. if ($this->get_debug())
  1155. $this->add_error_message('Failed to authenticate password. Error: '.$reply);
  1156. return FALSE;
  1157. }
  1158. return true;
  1159. }
  1160. /* END */
  1161. /** -------------------------------------
  1162. /** Send SMTP data
  1163. /** -------------------------------------*/
  1164. function send_data($data)
  1165. {
  1166. if ( ! fwrite($this->smtp_connect, $data . $this->newline))
  1167. {
  1168. if ($this->get_debug())
  1169. $this->add_error_message('Unable to send data: '.$data);
  1170. return FALSE;
  1171. }
  1172. else
  1173. return true;
  1174. }
  1175. /* END */
  1176. /** -------------------------------------
  1177. /** Get SMTP data
  1178. /** -------------------------------------*/
  1179. function get_data()
  1180. {
  1181. $data = "";
  1182. while ($str = fgets($this->smtp_connect, 512))
  1183. {
  1184. $data .= $str;
  1185. if (substr($str, 3, 1) == " ")
  1186. break;
  1187. }
  1188. return $data;
  1189. }
  1190. /* END */
  1191. /** -------------------------------------
  1192. /** Get Hostname
  1193. /** -------------------------------------*/
  1194. function get_hostname()
  1195. {
  1196. return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain';
  1197. }
  1198. /* END */
  1199. /** -------------------------------------
  1200. /** Add error Message
  1201. /** -------------------------------------*/
  1202. function add_error_message($msg)
  1203. {
  1204. $this->debug_msg[] = $msg.'<br />';
  1205. return FALSE;
  1206. }
  1207. /* END */
  1208. /** -------------------------------------
  1209. /** Show Error Message
  1210. /** -------------------------------------*/
  1211. function show_error_message()
  1212. {
  1213. $msg = '';
  1214. if (count($this->debug_msg) > 0)
  1215. {
  1216. foreach ($this->debug_msg as $val)
  1217. {
  1218. $msg .= $val;
  1219. }
  1220. }
  1221. return $msg;
  1222. }
  1223. /* END */
  1224. /** -------------------------------------
  1225. /** Good Message
  1226. /** -------------------------------------*/
  1227. function good_message($msg)
  1228. {
  1229. if ($this->get_debug())
  1230. $this->debug_msg[] = $msg."<br />";
  1231. }
  1232. /* END */
  1233. /** -------------------------------------
  1234. /** Print Sent Message
  1235. /** -------------------------------------*/
  1236. function print_message()
  1237. {
  1238. $this->debug_msg[] =
  1239. "<pre>".
  1240. $this->header_str."\n".
  1241. $this->subject."\n".
  1242. $this->finalbody.
  1243. "</pre>";
  1244. }
  1245. /* END */
  1246. /** -------------------------------------
  1247. /** Mime Types
  1248. /** -------------------------------------*/
  1249. function mime_types($ext = "")
  1250. {
  1251. $mimes = array( 'hqx' => 'application/mac-binhex40',
  1252. 'cpt' => 'application/mac-compactpro',
  1253. 'doc' => 'application/msword',
  1254. 'bin' => 'application/macbinary',
  1255. 'dms' => 'application/octet-stream',
  1256. 'lha' => 'application/octet-stream',
  1257. 'lzh' => 'application/octet-stream',
  1258. 'exe' => 'application/octet-stream',
  1259. 'class' => 'application/octet-stream',
  1260. 'psd' => 'application/octet-stream',
  1261. 'so' => 'application/octet-stream',
  1262. 'sea' => 'application/octet-stream',
  1263. 'dll' => 'application/octet-stream',
  1264. 'oda' => 'application/oda',
  1265. 'pdf' => 'application/pdf',
  1266. 'ai' => 'application/postscript',
  1267. 'eps' => 'application/postscript',
  1268. 'ps' => 'application/postscript',
  1269. 'smi' => 'application/smil',
  1270. 'smil' => 'application/smil',
  1271. 'mif' => 'application/vnd.mif',
  1272. 'xls' => 'application/vnd.ms-excel',
  1273. 'ppt' => 'application/vnd.ms-powerpoint',
  1274. 'wbxml' => 'application/vnd.wap.wbxml',
  1275. 'wmlc' => 'application/vnd.wap.wmlc',
  1276. 'dcr' => 'application/x-director',
  1277. 'dir' => 'application/x-director',
  1278. 'dxr' => 'application/x-director',
  1279. 'dvi' => 'application/x-dvi',
  1280. 'gtar' => 'application/x-gtar',
  1281. 'php' => 'application/x-httpd-php',
  1282. 'php4' => 'application/x-httpd-php',
  1283. 'php3' => 'application/x-httpd-php',
  1284. 'phtml' => 'application/x-httpd-php',
  1285. 'phps' => 'application/x-httpd-php-source',
  1286. 'js' => 'application/x-javascript',
  1287. 'swf' => 'application/x-shockwave-flash',
  1288. 'sit' => 'application/x-stuffit',
  1289. 'tar' => 'application/x-tar',
  1290. 'tgz' => 'application/x-tar',
  1291. 'xhtml' => 'application/xhtml+xml',
  1292. 'xht' => 'application/xhtml+xml',
  1293. 'zip' => 'application/zip',
  1294. 'mid' => 'audio/midi',
  1295. 'midi' => 'audio/midi',
  1296. 'mpga' => 'audio/mpeg',
  1297. 'mp2' => 'audio/mpeg',
  1298. 'mp3' => 'audio/mpeg',
  1299. 'aif' => 'audio/x-aiff',
  1300. 'aiff' => 'audio/x-aiff',
  1301. 'aifc' => 'audio/x-aiff',
  1302. 'ram' => 'audio/x-pn-realaudio',
  1303. 'rm' => 'audio/x-pn-realaudio',
  1304. 'rpm' => 'audio/x-pn-realaudio-plugin',
  1305. 'ra' => 'audio/x-realaudio',
  1306. 'rv' => 'video/vnd.rn-realvideo',
  1307. 'wav' => 'audio/x-wav',
  1308. 'bmp' => 'image/bmp',
  1309. 'gif' => 'image/gif',
  1310. 'jpeg' => 'image/jpeg',
  1311. 'jpg' => 'image/jpeg',
  1312. 'jpe' => 'image/jpeg',
  1313. 'png' => 'image/png',
  1314. 'tiff' => 'image/tiff',
  1315. 'tif' => 'image/tiff',
  1316. 'css' => 'text/css',
  1317. 'html' => 'text/html',
  1318. 'htm' => 'text/html',
  1319. 'shtml' => 'text/html',
  1320. 'txt' => 'text/plain',
  1321. 'text' => 'text/plain',
  1322. 'log' => 'text/plain',
  1323. 'rtx' => 'text/richtext',
  1324. 'rtf' => 'text/rtf',
  1325. 'xml' => 'text/xml',
  1326. 'xsl' => 'text/xml',
  1327. 'mpeg' => 'video/mpeg',
  1328. 'mpg' => 'video/mpeg',
  1329. 'mpe' => 'video/mpeg',
  1330. 'qt' => 'video/quicktime',
  1331. 'mov' => 'video/quicktime',
  1332. 'avi' => 'video/x-msvideo',
  1333. 'movie' => 'video/x-sgi-movie',
  1334. 'doc' => 'application/msword',
  1335. 'word' => 'application/msword',
  1336. 'xl' => 'application/excel',
  1337. 'eml' => 'message/rfc822'
  1338. );
  1339. return ( ! isset($mimes[strtolower($ext)])) ? "application/x-unknown-content-type" : $mimes[strtolower($ext)];
  1340. }
  1341. /* END */
  1342. }
  1343. // END CLASS
  1344. ?>