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
50: private $headers =
array();
53: private $parts =
array();
63: * @param string|array value or pair email => name
65: * @return MailMimePart provides a fluent interface
67: public function setHeader($name, $value, $append =
FALSE)
70: throw new InvalidArgumentException("Header name must be non-empty alphanumeric string, '$name' given.");
73: if ($value ==
NULL) { // intentionally ==
75: unset($this->headers[$name]);
79: $tmp =
& $this->headers[$name];
84: foreach ($value as $email =>
$name) {
85: if (!preg_match('#^[^@",\s]+@[^@",\s]+\.[a-z]{2,10}$#i', $email)) {
86: throw new InvalidArgumentException("Email address '$email' is not valid.");
90: throw new InvalidArgumentException("Name cannot contain the line separator.");
92: $tmp[$email] =
$name;
110: return isset($this->headers[$name]) ?
$this->headers[$name] :
NULL;
118: * @return MailMimePart provides a fluent interface
122: unset($this->headers[$name]);
129: * Returns an encoded header.
138: if (!isset($this->headers[$name])) {
143: foreach ($this->headers[$name] as $email =>
$name) {
144: if ($name !=
NULL) { // intentionally ==
145: $s .=
self::encodeQuotedPrintableHeader(
149: $email =
" <$email>";
151: if ($len +
strlen($email) +
1 >
self::LINE_LENGTH) {
152: $s .=
self::EOL .
' ';
161: return self::encodeQuotedPrintableHeader($this->headers[$name], $charset, $len);
168: * Returns all headers.
173: return $this->headers;
179: * Sets Content-Type header.
182: * @return MailMimePart provides a fluent interface
186: $this->setHeader('Content-Type', $contentType .
($charset ?
"; charset=$charset" :
''));
193: * Sets Content-Transfer-Encoding header.
195: * @return MailMimePart provides a fluent interface
206: * Returns Content-Transfer-Encoding header.
217: * Adds or creates new multipart.
218: * @param MailMimePart
219: * @return MailMimePart
221: public function addPart(MailMimePart $part =
NULL)
223: return $this->parts[] =
$part ===
NULL ?
new self :
$part;
229: * Sets textual body.
231: * @return MailMimePart provides a fluent interface
235: $this->body =
$body;
242: * Gets textual body.
252: /********************* building ****************d*g**/
257: * Returns encoded message.
265: foreach ($this->headers as $name =>
$value) {
267: if ($this->parts &&
$name ===
'Content-Type') {
268: $output .=
';' .
self::EOL .
"\tboundary=\"$boundary\"";
270: $output .=
self::EOL;
272: $output .=
self::EOL;
274: $body = (string)
$this->body;
277: case self::ENCODING_QUOTED_PRINTABLE:
278: $output .=
function_exists('quoted_printable_encode') ?
quoted_printable_encode($body) :
self::encodeQuotedPrintable($body);
281: case self::ENCODING_BASE64:
285: case self::ENCODING_7BIT:
287: // break intentionally omitted
289: case self::ENCODING_8BIT:
301: if (substr($output, -
strlen(self::EOL)) !==
self::EOL) $output .=
self::EOL;
302: foreach ($this->parts as $part) {
303: $output .=
'--' .
$boundary .
self::EOL .
$part->generateMessage() .
self::EOL;
305: $output .=
'--' .
$boundary.
'--';
313: /********************* QuotedPrintable helpers ****************d*g**/
318: * Converts a 8 bit header to a quoted-printable string.
324: private static function encodeQuotedPrintableHeader($s, $charset =
'UTF-8', & $len =
0)
326: $range =
'!"#$%&\'()*+,-./0123456789:;<>@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^`abcdefghijklmnopqrstuvwxyz{|}'; // \x21-\x7E without \x3D \x3F \x5F
332: $prefix =
"=?$charset?Q?";
337: while ($pos <
$size) {
339: while ($len +
$l >
self::LINE_LENGTH -
2) { // 2 = length of suffix ?=
340: $lx =
self::LINE_LENGTH -
$len -
2;
341: $o .=
substr($s, $pos, $lx) .
'?=' .
self::EOL .
' ' .
$prefix;
352: // \xC0 tests UTF-8 character boudnary; 9 is reserved space for 4bytes UTF-8 character
353: if (($s[$pos] & "\xC0") !==
"\x80" &&
$len >
self::LINE_LENGTH -
2 -
9) {
354: $o .=
'?=' .
self::EOL .
' ' .
$prefix;
367: * Converts a 8 bit string to a quoted-printable string.
373: $range =
'!"#$%&\'()*+,-./0123456789:;<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}'; // \x21-\x7E without \x3D
378: while ($pos <
$size) {
380: while ($len +
$l >
self::LINE_LENGTH -
1) { // 1 = length of suffix =
381: $lx =
self::LINE_LENGTH -
$len -
1;
382: $o .=
substr($s, $pos, $lx) .
'=' .
self::EOL;
393: if ($len >
self::LINE_LENGTH -
1) {
394: $o .=
'=' .
self::EOL;