Source for file MailMimePart.php
Documentation is available at MailMimePart.php
6: * Copyright (c) 2004, 2009 David Grudl (http://davidgrudl.com)
8: * This source file is subject to the "Nette license" that is bundled
9: * with this package in the file license.txt.
11: * For more information please see http://nettephp.com
13: * @copyright Copyright (c) 2004, 2009 David Grudl
14: * @license http://nettephp.com/license Nette license
15: * @link http://nettephp.com
17: * @package Nette\Mail
22: require_once dirname(__FILE__) .
'/../Object.php';
29: * @author David Grudl
30: * @copyright Copyright (c) 2004, 2009 David Grudl
31: * @package Nette\Mail
33: * @property string $encoding
34: * @property string $body
35: * @property-read array $headers
46: /**#@+ @ignore internal */
48: const LINE_LENGTH =
76;
52: private $headers =
array();
55: private $parts =
array();
65: * @param string|array value or pair email => name
67: * @return MailMimePart provides a fluent interface
69: public function setHeader($name, $value, $append =
FALSE)
72: throw new InvalidArgumentException("Header name must be non-empty alphanumeric string, '$name' given.");
75: if ($value ==
NULL) { // intentionally ==
77: unset($this->headers[$name]);
81: $tmp =
& $this->headers[$name];
86: foreach ($value as $email =>
$name) {
87: if (!preg_match('#^[^@",\s]+@[^@",\s]+\.[a-z]{2,10}$#i', $email)) {
88: throw new InvalidArgumentException("Email address '$email' is not valid.");
92: throw new InvalidArgumentException("Name cannot contain the line separator.");
94: $tmp[$email] =
$name;
112: return isset($this->headers[$name]) ?
$this->headers[$name] :
NULL;
120: * @return MailMimePart provides a fluent interface
124: unset($this->headers[$name]);
131: * Returns an encoded header.
140: if (!isset($this->headers[$name])) {
145: foreach ($this->headers[$name] as $email =>
$name) {
146: if ($name !=
NULL) { // intentionally ==
147: $s .=
self::encodeQuotedPrintableHeader(
151: $email =
" <$email>";
153: if ($len +
strlen($email) +
1 >
self::LINE_LENGTH) {
154: $s .=
self::EOL .
"\t";
163: return self::encodeQuotedPrintableHeader($this->headers[$name], $charset, $len);
170: * Returns all headers.
175: return $this->headers;
181: * Sets Content-Type header.
184: * @return MailMimePart provides a fluent interface
188: $this->setHeader('Content-Type', $contentType .
($charset ?
"; charset=$charset" :
''));
195: * Sets Content-Transfer-Encoding header.
197: * @return MailMimePart provides a fluent interface
208: * Returns Content-Transfer-Encoding header.
219: * Adds or creates new multipart.
220: * @param MailMimePart
221: * @return MailMimePart
223: public function addPart(MailMimePart $part =
NULL)
225: return $this->parts[] =
$part ===
NULL ?
new self :
$part;
231: * Sets textual body.
233: * @return MailMimePart provides a fluent interface
237: $this->body =
$body;
244: * Gets textual body.
254: /********************* building ****************d*g**/
259: * Returns encoded message.
267: foreach ($this->headers as $name =>
$value) {
269: if ($this->parts &&
$name ===
'Content-Type') {
270: $output .=
';' .
self::EOL .
"\tboundary=\"$boundary\"";
272: $output .=
self::EOL;
274: $output .=
self::EOL;
276: $body = (string)
$this->body;
279: case self::ENCODING_QUOTED_PRINTABLE:
280: $output .=
function_exists('quoted_printable_encode') ?
quoted_printable_encode($body) :
self::encodeQuotedPrintable($body);
283: case self::ENCODING_BASE64:
287: case self::ENCODING_7BIT:
289: // break intentionally omitted
291: case self::ENCODING_8BIT:
303: if (substr($output, -
strlen(self::EOL)) !==
self::EOL) $output .=
self::EOL;
304: foreach ($this->parts as $part) {
305: $output .=
'--' .
$boundary .
self::EOL .
$part->generateMessage() .
self::EOL;
307: $output .=
'--' .
$boundary.
'--';
315: /********************* QuotedPrintable helpers ****************d*g**/
320: * Converts a 8 bit header to a quoted-printable string.
326: private static function encodeQuotedPrintableHeader($s, $charset =
'UTF-8', & $len =
0)
328: $range =
'!"#$%&\'()*+,-./0123456789:;<>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^`abcdefghijklmnopqrstuvwxyz{|}'; // \x21-\x7E without \x3D \x3F \x5F
334: $prefix =
"=?$charset?Q?";
339: while ($pos <
$size) {
341: while ($len +
$l >
self::LINE_LENGTH -
2) { // 2 = length of suffix ?=
342: $lx =
self::LINE_LENGTH -
$len -
2;
343: $o .=
substr($s, $pos, $lx) .
'?=' .
self::EOL .
"\t" .
$prefix;
354: // \xC0 tests UTF-8 character boudnary; 9 is reserved space for 4bytes UTF-8 character
355: if (($s[$pos] & "\xC0") !==
"\x80" &&
$len >
self::LINE_LENGTH -
2 -
9) {
356: $o .=
'?=' .
self::EOL .
"\t" .
$prefix;
369: * Converts a 8 bit string to a quoted-printable string.
375: $range =
'!"#$%&\'()*+,-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}'; // \x21-\x7E without \x3D
380: while ($pos <
$size) {
382: while ($len +
$l >
self::LINE_LENGTH -
1) { // 1 = length of suffix =
383: $lx =
self::LINE_LENGTH -
$len -
1;
384: $o .=
substr($s, $pos, $lx) .
'=' .
self::EOL;
395: if ($len >
self::LINE_LENGTH -
1) {
396: $o .=
'=' .
self::EOL;