PageRenderTime 27ms CodeModel.GetById 0ms RepoModel.GetById 1ms app.codeStats 0ms

/htdocs/includes/nusoap/lib/Mail/mimePart.php

https://bitbucket.org/speedealing/speedealing
PHP | 350 lines | 136 code | 37 blank | 177 comment | 21 complexity | 2d2941bb2551e54d2c5d091a4aded9cd MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.1, GPL-3.0, MIT
  1. <?php
  2. // +-----------------------------------------------------------------------+
  3. // | Copyright (c) 2002-2003 Richard Heyes |
  4. // | All rights reserved. |
  5. // | |
  6. // | Redistribution and use in source and binary forms, with or without |
  7. // | modification, are permitted provided that the following conditions |
  8. // | are met: |
  9. // | |
  10. // | o Redistributions of source code must retain the above copyright |
  11. // | notice, this list of conditions and the following disclaimer. |
  12. // | o Redistributions in binary form must reproduce the above copyright |
  13. // | notice, this list of conditions and the following disclaimer in the |
  14. // | documentation and/or other materials provided with the distribution.|
  15. // | o The names of the authors may not be used to endorse or promote |
  16. // | products derived from this software without specific prior written |
  17. // | permission. |
  18. // | |
  19. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
  20. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
  21. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
  22. // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
  23. // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
  24. // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
  25. // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
  26. // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
  27. // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
  28. // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
  29. // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
  30. // | |
  31. // +-----------------------------------------------------------------------+
  32. // | Author: Richard Heyes <richard@phpguru.org> |
  33. // +-----------------------------------------------------------------------+
  34. /**
  35. *
  36. * Raw mime encoding class
  37. *
  38. * What is it?
  39. * This class enables you to manipulate and build
  40. * a mime email from the ground up.
  41. *
  42. * Why use this instead of mime.php?
  43. * mime.php is a userfriendly api to this class for
  44. * people who aren't interested in the internals of
  45. * mime mail. This class however allows full control
  46. * over the email.
  47. *
  48. * Eg.
  49. *
  50. * // Since multipart/mixed has no real body, (the body is
  51. * // the subpart), we set the body argument to blank.
  52. *
  53. * $params['content_type'] = 'multipart/mixed';
  54. * $email = new Mail_mimePart('', $params);
  55. *
  56. * // Here we add a text part to the multipart we have
  57. * // already. Assume $body contains plain text.
  58. *
  59. * $params['content_type'] = 'text/plain';
  60. * $params['encoding'] = '7bit';
  61. * $text = $email->addSubPart($body, $params);
  62. *
  63. * // Now add an attachment. Assume $attach is
  64. * the contents of the attachment
  65. *
  66. * $params['content_type'] = 'application/zip';
  67. * $params['encoding'] = 'base64';
  68. * $params['disposition'] = 'attachment';
  69. * $params['dfilename'] = 'example.zip';
  70. * $attach =& $email->addSubPart($body, $params);
  71. *
  72. * // Now build the email. Note that the encode
  73. * // function returns an associative array containing two
  74. * // elements, body and headers. You will need to add extra
  75. * // headers, (eg. Mime-Version) before sending.
  76. *
  77. * $email = $message->encode();
  78. * $email['headers'][] = 'Mime-Version: 1.0';
  79. *
  80. *
  81. * Further examples are available at http://www.phpguru.org
  82. *
  83. * TODO:
  84. * - Set encode() to return the $obj->encoded if encode()
  85. * has already been run. Unless a flag is passed to specifically
  86. * re-build the message.
  87. *
  88. * @author Richard Heyes <richard@phpguru.org>
  89. * @package Mail
  90. */
  91. class Mail_mimePart {
  92. /**
  93. * The encoding type of this part
  94. * @var string
  95. */
  96. var $_encoding;
  97. /**
  98. * An array of subparts
  99. * @var array
  100. */
  101. var $_subparts;
  102. /**
  103. * The output of this part after being built
  104. * @var string
  105. */
  106. var $_encoded;
  107. /**
  108. * Headers for this part
  109. * @var array
  110. */
  111. var $_headers;
  112. /**
  113. * The body of this part (not encoded)
  114. * @var string
  115. */
  116. var $_body;
  117. /**
  118. * Constructor.
  119. *
  120. * Sets up the object.
  121. *
  122. * @param $body - The body of the mime part if any.
  123. * @param $params - An associative array of parameters:
  124. * content_type - The content type for this part eg multipart/mixed
  125. * encoding - The encoding to use, 7bit, 8bit, base64, or quoted-printable
  126. * cid - Content ID to apply
  127. * disposition - Content disposition, inline or attachment
  128. * dfilename - Optional filename parameter for content disposition
  129. * description - Content description
  130. * charset - Character set to use
  131. * @access public
  132. */
  133. function Mail_mimePart($body = '', $params = array())
  134. {
  135. if (!defined('MAIL_MIMEPART_CRLF')) {
  136. define('MAIL_MIMEPART_CRLF', defined('MAIL_MIME_CRLF') ? MAIL_MIME_CRLF : "\r\n", TRUE);
  137. }
  138. foreach ($params as $key => $value) {
  139. switch ($key) {
  140. case 'content_type':
  141. $headers['Content-Type'] = $value . (isset($charset) ? '; charset="' . $charset . '"' : '');
  142. break;
  143. case 'encoding':
  144. $this->_encoding = $value;
  145. $headers['Content-Transfer-Encoding'] = $value;
  146. break;
  147. case 'cid':
  148. $headers['Content-ID'] = '<' . $value . '>';
  149. break;
  150. case 'disposition':
  151. $headers['Content-Disposition'] = $value . (isset($dfilename) ? '; filename="' . $dfilename . '"' : '');
  152. break;
  153. case 'dfilename':
  154. if (isset($headers['Content-Disposition'])) {
  155. $headers['Content-Disposition'] .= '; filename="' . $value . '"';
  156. } else {
  157. $dfilename = $value;
  158. }
  159. break;
  160. case 'description':
  161. $headers['Content-Description'] = $value;
  162. break;
  163. case 'charset':
  164. if (isset($headers['Content-Type'])) {
  165. $headers['Content-Type'] .= '; charset="' . $value . '"';
  166. } else {
  167. $charset = $value;
  168. }
  169. break;
  170. }
  171. }
  172. // Default content-type
  173. if (!isset($headers['Content-Type'])) {
  174. $headers['Content-Type'] = 'text/plain';
  175. }
  176. //Default encoding
  177. if (!isset($this->_encoding)) {
  178. $this->_encoding = '7bit';
  179. }
  180. // Assign stuff to member variables
  181. $this->_encoded = array();
  182. $this->_headers = $headers;
  183. $this->_body = $body;
  184. }
  185. /**
  186. * encode()
  187. *
  188. * Encodes and returns the email. Also stores
  189. * it in the encoded member variable
  190. *
  191. * @return An associative array containing two elements,
  192. * body and headers. The headers element is itself
  193. * an indexed array.
  194. * @access public
  195. */
  196. function encode()
  197. {
  198. $encoded =& $this->_encoded;
  199. if (!empty($this->_subparts)) {
  200. srand((double)microtime()*1000000);
  201. $boundary = '=_' . md5(rand() . microtime());
  202. $this->_headers['Content-Type'] .= ';' . MAIL_MIMEPART_CRLF . "\t" . 'boundary="' . $boundary . '"';
  203. // Add body parts to $subparts
  204. for ($i = 0; $i < count($this->_subparts); $i++) {
  205. $headers = array();
  206. $tmp = $this->_subparts[$i]->encode();
  207. foreach ($tmp['headers'] as $key => $value) {
  208. $headers[] = $key . ': ' . $value;
  209. }
  210. $subparts[] = implode(MAIL_MIMEPART_CRLF, $headers) . MAIL_MIMEPART_CRLF . MAIL_MIMEPART_CRLF . $tmp['body'];
  211. }
  212. $encoded['body'] = '--' . $boundary . MAIL_MIMEPART_CRLF .
  213. implode('--' . $boundary . MAIL_MIMEPART_CRLF, $subparts) .
  214. '--' . $boundary.'--' . MAIL_MIMEPART_CRLF;
  215. } else {
  216. $encoded['body'] = $this->_getEncodedData($this->_body, $this->_encoding) . MAIL_MIMEPART_CRLF;
  217. }
  218. // Add headers to $encoded
  219. $encoded['headers'] =& $this->_headers;
  220. return $encoded;
  221. }
  222. /**
  223. * &addSubPart()
  224. *
  225. * Adds a subpart to current mime part and returns
  226. * a reference to it
  227. *
  228. * @param $body The body of the subpart, if any.
  229. * @param $params The parameters for the subpart, same
  230. * as the $params argument for constructor.
  231. * @return A reference to the part you just added. It is
  232. * crucial if using multipart/* in your subparts that
  233. * you use =& in your script when calling this function,
  234. * otherwise you will not be able to add further subparts.
  235. * @access public
  236. */
  237. function &addSubPart($body, $params)
  238. {
  239. $this->_subparts[] = new Mail_mimePart($body, $params);
  240. return $this->_subparts[count($this->_subparts) - 1];
  241. }
  242. /**
  243. * _getEncodedData()
  244. *
  245. * Returns encoded data based upon encoding passed to it
  246. *
  247. * @param $data The data to encode.
  248. * @param $encoding The encoding type to use, 7bit, base64,
  249. * or quoted-printable.
  250. * @access private
  251. */
  252. function _getEncodedData($data, $encoding)
  253. {
  254. switch ($encoding) {
  255. case '8bit':
  256. case '7bit':
  257. return $data;
  258. break;
  259. case 'quoted-printable':
  260. return $this->_quotedPrintableEncode($data);
  261. break;
  262. case 'base64':
  263. return rtrim(chunk_split(base64_encode($data), 76, MAIL_MIMEPART_CRLF));
  264. break;
  265. default:
  266. return $data;
  267. }
  268. }
  269. /**
  270. * quoteadPrintableEncode()
  271. *
  272. * Encodes data to quoted-printable standard.
  273. *
  274. * @param $input The data to encode
  275. * @param $line_max Optional max line length. Should
  276. * not be more than 76 chars
  277. *
  278. * @access private
  279. */
  280. function _quotedPrintableEncode($input , $line_max = 76)
  281. {
  282. $lines = preg_split("/\r?\n/", $input);
  283. $eol = MAIL_MIMEPART_CRLF;
  284. $escape = '=';
  285. $output = '';
  286. while(list(, $line) = each($lines)){
  287. $linlen = strlen($line);
  288. $newline = '';
  289. for ($i = 0; $i < $linlen; $i++) {
  290. $char = substr($line, $i, 1);
  291. $dec = ord($char);
  292. if (($dec == 32) AND ($i == ($linlen - 1))){ // convert space at eol only
  293. $char = '=20';
  294. } elseif(($dec == 9) AND ($i == ($linlen - 1))) { // convert tab at eol only
  295. $char = '=09';
  296. } elseif($dec == 9) {
  297. ; // Do nothing if a tab.
  298. } elseif(($dec == 61) OR ($dec < 32 ) OR ($dec > 126)) {
  299. $char = $escape . strtoupper(sprintf('%02s', dechex($dec)));
  300. }
  301. if ((strlen($newline) + strlen($char)) >= $line_max) { // MAIL_MIMEPART_CRLF is not counted
  302. $output .= $newline . $escape . $eol; // soft line break; " =\r\n" is okay
  303. $newline = '';
  304. }
  305. $newline .= $char;
  306. } // end of for
  307. $output .= $newline . $eol;
  308. }
  309. $output = substr($output, 0, -1 * strlen($eol)); // Don't want last crlf
  310. return $output;
  311. }
  312. } // End of class
  313. ?>