PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/0.1/ccds_library/htmlMimeMail5/mimePart.php

http://ccds.googlecode.com/
PHP | 320 lines | 135 code | 36 blank | 149 comment | 19 complexity | d76cbdc8df2b67a7a26fd802517dd823 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. /**
  3. * This file is part of the htmlMimeMail5 package (http://www.phpguru.org/)
  4. *
  5. * htmlMimeMail5 is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * htmlMimeMail5 is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with htmlMimeMail5; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. * Š Copyright 2005 Richard Heyes
  20. */
  21. /**
  22. *
  23. * Raw mime encoding class
  24. *
  25. * What is it?
  26. * This class enables you to manipulate and build
  27. * a mime email from the ground up.
  28. *
  29. * Why use this instead of mime.php?
  30. * mime.php is a userfriendly api to this class for
  31. * people who aren't interested in the internals of
  32. * mime mail. This class however allows full control
  33. * over the email.
  34. *
  35. * Eg.
  36. *
  37. * // Since multipart/mixed has no real body, (the body is
  38. * // the subpart), we set the body argument to blank.
  39. *
  40. * $params['content_type'] = 'multipart/mixed';
  41. * $email = new Mail_mimePart('', $params);
  42. *
  43. * // Here we add a text part to the multipart we have
  44. * // already. Assume $body contains plain text.
  45. *
  46. * $params['content_type'] = 'text/plain';
  47. * $params['encoding'] = '7bit';
  48. * $text = $email->addSubPart($body, $params);
  49. *
  50. * // Now add an attachment. Assume $attach is
  51. * the contents of the attachment
  52. *
  53. * $params['content_type'] = 'application/zip';
  54. * $params['encoding'] = 'base64';
  55. * $params['disposition'] = 'attachment';
  56. * $params['dfilename'] = 'example.zip';
  57. * $attach =& $email->addSubPart($body, $params);
  58. *
  59. * // Now build the email. Note that the encode
  60. * // function returns an associative array containing two
  61. * // elements, body and headers. You will need to add extra
  62. * // headers, (eg. Mime-Version) before sending.
  63. *
  64. * $email = $message->encode();
  65. * $email['headers'][] = 'Mime-Version: 1.0';
  66. *
  67. *
  68. * Further examples are available at http://www.phpguru.org
  69. *
  70. * TODO:
  71. * - Set encode() to return the $obj->encoded if encode()
  72. * has already been run. Unless a flag is passed to specifically
  73. * re-build the message.
  74. *
  75. * @author Richard Heyes <richard@phpguru.org>
  76. * @version $Revision: 1.3 $
  77. * @package Mail
  78. */
  79. class Mail_MIMEPart
  80. {
  81. /**
  82. * The encoding type of this part
  83. * @var string
  84. */
  85. private $encoding;
  86. /**
  87. * An array of subparts
  88. * @var array
  89. */
  90. private $subparts;
  91. /**
  92. * The output of this part after being built
  93. * @var string
  94. */
  95. private $encoded;
  96. /**
  97. * Headers for this part
  98. * @var array
  99. */
  100. private $headers;
  101. /**
  102. * The body of this part (not encoded)
  103. * @var string
  104. */
  105. private $body;
  106. /**
  107. * Constructor.
  108. *
  109. * Sets up the object.
  110. *
  111. * @param $body - The body of the mime part if any.
  112. * @param $params - An associative array of parameters:
  113. * content_type - The content type for this part eg multipart/mixed
  114. * encoding - The encoding to use, 7bit, 8bit, base64, or quoted-printable
  115. * cid - Content ID to apply
  116. * disposition - Content disposition, inline or attachment
  117. * dfilename - Optional filename parameter for content disposition
  118. * description - Content description
  119. * charset - Character set to use
  120. * @access public
  121. */
  122. public function __construct($body = '', $params = array())
  123. {
  124. if (!defined('MAIL_MIMEPART_CRLF')) {
  125. define('MAIL_MIMEPART_CRLF', defined('MAIL_MIME_CRLF') ? MAIL_MIME_CRLF : "\r\n", true);
  126. }
  127. foreach ($params as $key => $value) {
  128. switch ($key) {
  129. case 'content_type':
  130. $headers['Content-Type'] = $value . (isset($charset) ? '; charset="' . $charset . '"' : '');
  131. break;
  132. case 'encoding':
  133. $this->encoding = $value;
  134. $headers['Content-Transfer-Encoding'] = $value;
  135. break;
  136. case 'cid':
  137. $headers['Content-ID'] = '<' . $value . '>';
  138. break;
  139. case 'disposition':
  140. $headers['Content-Disposition'] = $value . (isset($dfilename) ? '; filename="' . $dfilename . '"' : '');
  141. break;
  142. case 'dfilename':
  143. if (isset($headers['Content-Disposition'])) {
  144. $headers['Content-Disposition'] .= '; filename="' . $value . '"';
  145. } else {
  146. $dfilename = $value;
  147. }
  148. break;
  149. case 'description':
  150. $headers['Content-Description'] = $value;
  151. break;
  152. case 'charset':
  153. if (isset($headers['Content-Type'])) {
  154. $headers['Content-Type'] .= '; charset="' . $value . '"';
  155. } else {
  156. $charset = $value;
  157. }
  158. break;
  159. }
  160. }
  161. // Default content-type
  162. if (!isset($headers['Content-Type'])) {
  163. $headers['Content-Type'] = 'text/plain';
  164. }
  165. // Default encoding
  166. if (!isset($this->encoding)) {
  167. $this->encoding = '7bit';
  168. }
  169. // Assign stuff to member variables
  170. $this->encoded = array();
  171. $this->headers = $headers;
  172. $this->body = $body;
  173. }
  174. /**
  175. * Encodes and returns the email. Also stores
  176. * it in the encoded member variable
  177. *
  178. * @return An associative array containing two elements,
  179. * body and headers. The headers element is itself
  180. * an indexed array.
  181. */
  182. public function encode()
  183. {
  184. $encoded =& $this->encoded;
  185. if (!empty($this->subparts)) {
  186. srand((double)microtime()*1000000);
  187. $boundary = '=_' . md5(uniqid(rand()) . microtime());
  188. $this->headers['Content-Type'] .= ';' . MAIL_MIMEPART_CRLF . "\t" . 'boundary="' . $boundary . '"';
  189. // Add body parts to $subparts
  190. for ($i = 0; $i < count($this->subparts); $i++) {
  191. $headers = array();
  192. $tmp = $this->subparts[$i]->encode();
  193. foreach ($tmp['headers'] as $key => $value) {
  194. $headers[] = $key . ': ' . $value;
  195. }
  196. $subparts[] = implode(MAIL_MIMEPART_CRLF, $headers) . MAIL_MIMEPART_CRLF . MAIL_MIMEPART_CRLF . $tmp['body'];
  197. }
  198. $encoded['body'] = '--' . $boundary . MAIL_MIMEPART_CRLF .
  199. implode('--' . $boundary . MAIL_MIMEPART_CRLF, $subparts) .
  200. '--' . $boundary.'--' . MAIL_MIMEPART_CRLF;
  201. } else {
  202. $encoded['body'] = $this->getEncodedData($this->body, $this->encoding) . MAIL_MIMEPART_CRLF;
  203. }
  204. // Add headers to $encoded
  205. $encoded['headers'] =& $this->headers;
  206. return $encoded;
  207. }
  208. /**
  209. * Adds a subpart to current mime part and returns
  210. * a reference to it
  211. *
  212. * @param $body The body of the subpart, if any.
  213. * @param $params The parameters for the subpart, same
  214. * as the $params argument for constructor.
  215. * @return A reference to the part you just added.
  216. */
  217. public function addSubPart($body, $params)
  218. {
  219. $this->subparts[] = new Mail_MIMEPart($body, $params);
  220. return $this->subparts[count($this->subparts) - 1];
  221. }
  222. /**
  223. * Returns encoded data based upon encoding passed to it
  224. *
  225. * @param $data The data to encode.
  226. * @param $encoding The encoding type to use, 7bit, base64,
  227. * or quoted-printable.
  228. */
  229. private function getEncodedData($data, $encoding)
  230. {
  231. switch ($encoding) {
  232. case '8bit':
  233. case '7bit':
  234. return $data;
  235. break;
  236. case 'quoted-printable':
  237. return $this->quotedPrintableEncode($data);
  238. break;
  239. case 'base64':
  240. return rtrim(chunk_split(base64_encode($data), 76, MAIL_MIMEPART_CRLF));
  241. break;
  242. default:
  243. return $data;
  244. }
  245. }
  246. /**
  247. * Encodes data to quoted-printable standard.
  248. *
  249. * @param $input The data to encode
  250. * @param $line_max Optional max line length. Should
  251. * not be more than 76 chars
  252. */
  253. private function quotedPrintableEncode($input , $line_max = 76)
  254. {
  255. $lines = preg_split("/\r?\n/", $input);
  256. $eol = MAIL_MIMEPART_CRLF;
  257. $escape = '=';
  258. $output = '';
  259. while(list(, $line) = each($lines)){
  260. $linlen = strlen($line);
  261. $newline = '';
  262. for ($i = 0; $i < $linlen; $i++) {
  263. $char = substr($line, $i, 1);
  264. $dec = ord($char);
  265. if (($dec == 32) AND ($i == ($linlen - 1))){ // convert space at eol only
  266. $char = '=20';
  267. } elseif($dec == 9) {
  268. ; // Do nothing if a tab.
  269. } elseif(($dec == 61) OR ($dec < 32 ) OR ($dec > 126)) {
  270. $char = $escape . strtoupper(sprintf('%02s', dechex($dec)));
  271. }
  272. if ((strlen($newline) + strlen($char)) >= $line_max) { // MAIL_MIMEPART_CRLF is not counted
  273. $output .= $newline . $escape . $eol; // soft line break; " =\r\n" is okay
  274. $newline = '';
  275. }
  276. $newline .= $char;
  277. } // end of for
  278. $output .= $newline . $eol;
  279. }
  280. $output = substr($output, 0, -1 * strlen($eol)); // Don't want last crlf
  281. return $output;
  282. }
  283. } // End of class
  284. ?>