summaryrefslogtreecommitdiffstats
path: root/library/vendor/Zend/Mime
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/vendor/Zend/Mime.php670
-rw-r--r--library/vendor/Zend/Mime/Decode.php275
-rw-r--r--library/vendor/Zend/Mime/Exception.php35
-rw-r--r--library/vendor/Zend/Mime/Message.php302
-rw-r--r--library/vendor/Zend/Mime/Part.php329
5 files changed, 1611 insertions, 0 deletions
diff --git a/library/vendor/Zend/Mime.php b/library/vendor/Zend/Mime.php
new file mode 100644
index 0000000..5530b6c
--- /dev/null
+++ b/library/vendor/Zend/Mime.php
@@ -0,0 +1,670 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Mime
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Support class for MultiPart Mime Messages
+ *
+ * @category Zend
+ * @package Zend_Mime
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Mime
+{
+ const TYPE_OCTETSTREAM = 'application/octet-stream';
+ const TYPE_TEXT = 'text/plain';
+ const TYPE_HTML = 'text/html';
+ const ENCODING_7BIT = '7bit';
+ const ENCODING_8BIT = '8bit';
+ const ENCODING_QUOTEDPRINTABLE = 'quoted-printable';
+ const ENCODING_BASE64 = 'base64';
+ const DISPOSITION_ATTACHMENT = 'attachment';
+ const DISPOSITION_INLINE = 'inline';
+ const LINELENGTH = 72;
+ const LINEEND = "\n";
+ const MULTIPART_ALTERNATIVE = 'multipart/alternative';
+ const MULTIPART_MIXED = 'multipart/mixed';
+ const MULTIPART_RELATED = 'multipart/related';
+
+ /**
+ * Boundary
+ *
+ * @var null|string
+ */
+ protected $_boundary;
+
+ /**
+ * @var int
+ */
+ protected static $makeUnique = 0;
+
+ /**
+ * Lookup-Tables for QuotedPrintable
+ *
+ * @var array
+ */
+ public static $qpKeys = array(
+ "\x00",
+ "\x01",
+ "\x02",
+ "\x03",
+ "\x04",
+ "\x05",
+ "\x06",
+ "\x07",
+ "\x08",
+ "\x09",
+ "\x0A",
+ "\x0B",
+ "\x0C",
+ "\x0D",
+ "\x0E",
+ "\x0F",
+ "\x10",
+ "\x11",
+ "\x12",
+ "\x13",
+ "\x14",
+ "\x15",
+ "\x16",
+ "\x17",
+ "\x18",
+ "\x19",
+ "\x1A",
+ "\x1B",
+ "\x1C",
+ "\x1D",
+ "\x1E",
+ "\x1F",
+ "\x7F",
+ "\x80",
+ "\x81",
+ "\x82",
+ "\x83",
+ "\x84",
+ "\x85",
+ "\x86",
+ "\x87",
+ "\x88",
+ "\x89",
+ "\x8A",
+ "\x8B",
+ "\x8C",
+ "\x8D",
+ "\x8E",
+ "\x8F",
+ "\x90",
+ "\x91",
+ "\x92",
+ "\x93",
+ "\x94",
+ "\x95",
+ "\x96",
+ "\x97",
+ "\x98",
+ "\x99",
+ "\x9A",
+ "\x9B",
+ "\x9C",
+ "\x9D",
+ "\x9E",
+ "\x9F",
+ "\xA0",
+ "\xA1",
+ "\xA2",
+ "\xA3",
+ "\xA4",
+ "\xA5",
+ "\xA6",
+ "\xA7",
+ "\xA8",
+ "\xA9",
+ "\xAA",
+ "\xAB",
+ "\xAC",
+ "\xAD",
+ "\xAE",
+ "\xAF",
+ "\xB0",
+ "\xB1",
+ "\xB2",
+ "\xB3",
+ "\xB4",
+ "\xB5",
+ "\xB6",
+ "\xB7",
+ "\xB8",
+ "\xB9",
+ "\xBA",
+ "\xBB",
+ "\xBC",
+ "\xBD",
+ "\xBE",
+ "\xBF",
+ "\xC0",
+ "\xC1",
+ "\xC2",
+ "\xC3",
+ "\xC4",
+ "\xC5",
+ "\xC6",
+ "\xC7",
+ "\xC8",
+ "\xC9",
+ "\xCA",
+ "\xCB",
+ "\xCC",
+ "\xCD",
+ "\xCE",
+ "\xCF",
+ "\xD0",
+ "\xD1",
+ "\xD2",
+ "\xD3",
+ "\xD4",
+ "\xD5",
+ "\xD6",
+ "\xD7",
+ "\xD8",
+ "\xD9",
+ "\xDA",
+ "\xDB",
+ "\xDC",
+ "\xDD",
+ "\xDE",
+ "\xDF",
+ "\xE0",
+ "\xE1",
+ "\xE2",
+ "\xE3",
+ "\xE4",
+ "\xE5",
+ "\xE6",
+ "\xE7",
+ "\xE8",
+ "\xE9",
+ "\xEA",
+ "\xEB",
+ "\xEC",
+ "\xED",
+ "\xEE",
+ "\xEF",
+ "\xF0",
+ "\xF1",
+ "\xF2",
+ "\xF3",
+ "\xF4",
+ "\xF5",
+ "\xF6",
+ "\xF7",
+ "\xF8",
+ "\xF9",
+ "\xFA",
+ "\xFB",
+ "\xFC",
+ "\xFD",
+ "\xFE",
+ "\xFF"
+ );
+
+ /**
+ * @var array
+ */
+ public static $qpReplaceValues = array(
+ "=00",
+ "=01",
+ "=02",
+ "=03",
+ "=04",
+ "=05",
+ "=06",
+ "=07",
+ "=08",
+ "=09",
+ "=0A",
+ "=0B",
+ "=0C",
+ "=0D",
+ "=0E",
+ "=0F",
+ "=10",
+ "=11",
+ "=12",
+ "=13",
+ "=14",
+ "=15",
+ "=16",
+ "=17",
+ "=18",
+ "=19",
+ "=1A",
+ "=1B",
+ "=1C",
+ "=1D",
+ "=1E",
+ "=1F",
+ "=7F",
+ "=80",
+ "=81",
+ "=82",
+ "=83",
+ "=84",
+ "=85",
+ "=86",
+ "=87",
+ "=88",
+ "=89",
+ "=8A",
+ "=8B",
+ "=8C",
+ "=8D",
+ "=8E",
+ "=8F",
+ "=90",
+ "=91",
+ "=92",
+ "=93",
+ "=94",
+ "=95",
+ "=96",
+ "=97",
+ "=98",
+ "=99",
+ "=9A",
+ "=9B",
+ "=9C",
+ "=9D",
+ "=9E",
+ "=9F",
+ "=A0",
+ "=A1",
+ "=A2",
+ "=A3",
+ "=A4",
+ "=A5",
+ "=A6",
+ "=A7",
+ "=A8",
+ "=A9",
+ "=AA",
+ "=AB",
+ "=AC",
+ "=AD",
+ "=AE",
+ "=AF",
+ "=B0",
+ "=B1",
+ "=B2",
+ "=B3",
+ "=B4",
+ "=B5",
+ "=B6",
+ "=B7",
+ "=B8",
+ "=B9",
+ "=BA",
+ "=BB",
+ "=BC",
+ "=BD",
+ "=BE",
+ "=BF",
+ "=C0",
+ "=C1",
+ "=C2",
+ "=C3",
+ "=C4",
+ "=C5",
+ "=C6",
+ "=C7",
+ "=C8",
+ "=C9",
+ "=CA",
+ "=CB",
+ "=CC",
+ "=CD",
+ "=CE",
+ "=CF",
+ "=D0",
+ "=D1",
+ "=D2",
+ "=D3",
+ "=D4",
+ "=D5",
+ "=D6",
+ "=D7",
+ "=D8",
+ "=D9",
+ "=DA",
+ "=DB",
+ "=DC",
+ "=DD",
+ "=DE",
+ "=DF",
+ "=E0",
+ "=E1",
+ "=E2",
+ "=E3",
+ "=E4",
+ "=E5",
+ "=E6",
+ "=E7",
+ "=E8",
+ "=E9",
+ "=EA",
+ "=EB",
+ "=EC",
+ "=ED",
+ "=EE",
+ "=EF",
+ "=F0",
+ "=F1",
+ "=F2",
+ "=F3",
+ "=F4",
+ "=F5",
+ "=F6",
+ "=F7",
+ "=F8",
+ "=F9",
+ "=FA",
+ "=FB",
+ "=FC",
+ "=FD",
+ "=FE",
+ "=FF"
+ );
+
+ /**
+ * @var string
+ */
+ public static $qpKeysString =
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF";
+
+ /**
+ * Check if the given string is "printable"
+ *
+ * Checks that a string contains no unprintable characters. If this returns
+ * false, encode the string for secure delivery.
+ *
+ * @param string $str
+ * @return boolean
+ */
+ public static function isPrintable($str)
+ {
+ return (strcspn($str, self::$qpKeysString) == strlen($str));
+ }
+
+ /**
+ * Encode a given string with the QUOTED_PRINTABLE mechanism and wrap the lines.
+ *
+ * @param string $str
+ * @param int $lineLength Line length; defaults to {@link LINELENGTH}
+ * @param string $lineEnd Line end; defaults to {@link LINEEND}
+ * @return string
+ */
+ public static function encodeQuotedPrintable(
+ $str,
+ $lineLength = self::LINELENGTH,
+ $lineEnd = self::LINEEND
+ )
+ {
+ $out = '';
+ $str = self::_encodeQuotedPrintable($str);
+
+ // Split encoded text into separate lines
+ while (strlen($str) > 0) {
+ $ptr = strlen($str);
+ if ($ptr > $lineLength) {
+ $ptr = $lineLength;
+ }
+
+ // Ensure we are not splitting across an encoded character
+ $pos = strrpos(substr($str, 0, $ptr), '=');
+ if ($pos !== false && $pos >= $ptr - 2) {
+ $ptr = $pos;
+ }
+
+ // Check if there is a space at the end of the line and rewind
+ if ($ptr > 0 && $str[$ptr - 1] == ' ') {
+ --$ptr;
+ }
+
+ // Add string and continue
+ $out .= substr($str, 0, $ptr) . '=' . $lineEnd;
+ $str = substr($str, $ptr);
+ }
+
+ $out = rtrim($out, $lineEnd);
+ $out = rtrim($out, '=');
+
+ return $out;
+ }
+
+ /**
+ * Converts a string into quoted printable format.
+ *
+ * @param string $str
+ * @return string
+ */
+ private static function _encodeQuotedPrintable($str)
+ {
+ $str = str_replace('=', '=3D', $str);
+ $str = str_replace(self::$qpKeys, self::$qpReplaceValues, $str);
+ $str = rtrim($str);
+
+ return $str;
+ }
+
+ /**
+ * Encode a given string with the QUOTED_PRINTABLE mechanism for Mail Headers.
+ *
+ * Mail headers depend on an extended quoted printable algorithm otherwise
+ * a range of bugs can occur.
+ *
+ * @param string $str
+ * @param string $charset
+ * @param int $lineLength Line length; defaults to {@link LINELENGTH}
+ * @param string $lineEnd Line end; defaults to {@link LINEEND}
+ * @return string
+ */
+ public static function encodeQuotedPrintableHeader(
+ $str, $charset, $lineLength = self::LINELENGTH, $lineEnd = self::LINEEND
+ )
+ {
+ // Reduce line-length by the length of the required delimiter, charsets and encoding
+ $prefix = sprintf('=?%s?Q?', $charset);
+ $lineLength = $lineLength - strlen($prefix) - 3;
+
+ $str = self::_encodeQuotedPrintable($str);
+
+ // Mail-Header required chars have to be encoded also:
+ $str = str_replace(
+ array('?', ' ', '_', ','), array('=3F', '=20', '=5F', '=2C'), $str
+ );
+
+ // initialize first line, we need it anyways
+ $lines = array(0 => "");
+
+ // Split encoded text into separate lines
+ $tmp = "";
+ while (strlen($str) > 0) {
+ $currentLine = max(count($lines) - 1, 0);
+ $token = self::getNextQuotedPrintableToken($str);
+ $str = substr($str, strlen($token));
+
+ $tmp .= $token;
+ if ($token == '=20') {
+ // only if we have a single char token or space, we can append the
+ // tempstring it to the current line or start a new line if necessary.
+ if (strlen($lines[$currentLine] . $tmp) > $lineLength) {
+ $lines[$currentLine + 1] = $tmp;
+ } else {
+ $lines[$currentLine] .= $tmp;
+ }
+ $tmp = "";
+ }
+ // don't forget to append the rest to the last line
+ if (strlen($str) == 0) {
+ $lines[$currentLine] .= $tmp;
+ }
+ }
+
+ // assemble the lines together by pre- and appending delimiters, charset, encoding.
+ for ($i = 0; $i < count($lines); $i++) {
+ $lines[$i] = " " . $prefix . $lines[$i] . "?=";
+ }
+ $str = trim(implode($lineEnd, $lines));
+
+ return $str;
+ }
+
+ /**
+ * Retrieves the first token from a quoted printable string.
+ *
+ * @param string $str
+ * @return string
+ */
+ private static function getNextQuotedPrintableToken($str)
+ {
+ if (substr($str, 0, 1) == "=") {
+ $token = substr($str, 0, 3);
+ } else {
+ $token = substr($str, 0, 1);
+ }
+
+ return $token;
+ }
+
+ /**
+ * Encode a given string in mail header compatible base64 encoding.
+ *
+ * @param string $str
+ * @param string $charset
+ * @param int $lineLength Line length; defaults to {@link LINELENGTH}
+ * @param string $lineEnd Line end; defaults to {@link LINEEND}
+ * @return string
+ */
+ public static function encodeBase64Header(
+ $str, $charset, $lineLength = self::LINELENGTH, $lineEnd = self::LINEEND
+ )
+ {
+ $prefix = '=?' . $charset . '?B?';
+ $suffix = '?=';
+ $remainingLength = $lineLength - strlen($prefix) - strlen($suffix);
+
+ $encodedValue = self::encodeBase64($str, $remainingLength, $lineEnd);
+ $encodedValue = str_replace(
+ $lineEnd, $suffix . $lineEnd . ' ' . $prefix, $encodedValue
+ );
+ $encodedValue = $prefix . $encodedValue . $suffix;
+
+ return $encodedValue;
+ }
+
+ /**
+ * Encode a given string in base64 encoding and break lines
+ * according to the maximum linelength.
+ *
+ * @param string $str
+ * @param int $lineLength Line length; defaults to {@link LINELENGTH}
+ * @param string $lineEnd Line end; defaults to {@link LINEEND}
+ * @return string
+ */
+ public static function encodeBase64(
+ $str, $lineLength = self::LINELENGTH, $lineEnd = self::LINEEND
+ )
+ {
+ return rtrim(chunk_split(base64_encode($str), $lineLength, $lineEnd));
+ }
+
+ /**
+ * Constructor
+ *
+ * @param null|string $boundary
+ */
+ public function __construct($boundary = null)
+ {
+ // This string needs to be somewhat unique
+ if ($boundary === null) {
+ $this->_boundary = '=_' . md5(microtime(1) . self::$makeUnique++);
+ } else {
+ $this->_boundary = $boundary;
+ }
+ }
+
+ /**
+ * Encode the given string with the given encoding.
+ *
+ * @param string $str
+ * @param string $encoding
+ * @param string $EOL Line end; defaults to {@link Zend_Mime::LINEEND}
+ * @return string
+ */
+ public static function encode($str, $encoding, $EOL = self::LINEEND)
+ {
+ switch ($encoding) {
+ case self::ENCODING_BASE64:
+ return self::encodeBase64($str, self::LINELENGTH, $EOL);
+
+ case self::ENCODING_QUOTEDPRINTABLE:
+ return self::encodeQuotedPrintable($str, self::LINELENGTH, $EOL);
+
+ default:
+ /**
+ * @todo 7Bit and 8Bit is currently handled the same way.
+ */
+ return $str;
+ }
+ }
+
+ /**
+ * Return a MIME boundary
+ *
+ * @access public
+ * @return string
+ */
+ public function boundary()
+ {
+ return $this->_boundary;
+ }
+
+ /**
+ * Return a MIME boundary line
+ *
+ * @param string $EOL Line end; defaults to {@link LINEEND}
+ * @return string
+ */
+ public function boundaryLine($EOL = self::LINEEND)
+ {
+ return $EOL . '--' . $this->_boundary . $EOL;
+ }
+
+ /**
+ * Return MIME ending
+ *
+ * @param string $EOL Line end; defaults to {@link LINEEND}
+ * @return string
+ */
+ public function mimeEnd($EOL = self::LINEEND)
+ {
+ return $EOL . '--' . $this->_boundary . '--' . $EOL;
+ }
+}
diff --git a/library/vendor/Zend/Mime/Decode.php b/library/vendor/Zend/Mime/Decode.php
new file mode 100644
index 0000000..a63f861
--- /dev/null
+++ b/library/vendor/Zend/Mime/Decode.php
@@ -0,0 +1,275 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Mime
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * @see Zend_Mime
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Mime
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Mime_Decode
+{
+ /**
+ * Explode MIME multipart string into seperate parts
+ *
+ * Parts consist of the header and the body of each MIME part.
+ *
+ * @param string $body raw body of message
+ * @param string $boundary boundary as found in content-type
+ * @return array parts with content of each part, empty if no parts found
+ * @throws Zend_Exception
+ */
+ public static function splitMime($body, $boundary)
+ {
+ // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
+ $body = str_replace("\r", '', $body);
+
+ $start = 0;
+ $res = array();
+ // find every mime part limiter and cut out the
+ // string before it.
+ // the part before the first boundary string is discarded:
+ $p = strpos($body, '--' . $boundary . "\n", $start);
+ if ($p === false) {
+ // no parts found!
+ return array();
+ }
+
+ // position after first boundary line
+ $start = $p + 3 + strlen($boundary);
+
+ while (($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) {
+ $res[] = substr($body, $start, $p-$start);
+ $start = $p + 3 + strlen($boundary);
+ }
+
+ // no more parts, find end boundary
+ $p = strpos($body, '--' . $boundary . '--', $start);
+ if ($p === false) {
+ throw new Zend_Exception('Not a valid Mime Message: End Missing');
+ }
+
+ // the remaining part also needs to be parsed:
+ $res[] = substr($body, $start, $p - $start);
+
+ return $res;
+ }
+
+ /**
+ * decodes a mime encoded String and returns a
+ * struct of parts with header and body
+ *
+ * @param string $message raw message content
+ * @param string $boundary boundary as found in content-type
+ * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
+ * @return array|null parts as array('header' => array(name => value), 'body' => content), null if no parts found
+ * @throws Zend_Exception
+ */
+ public static function splitMessageStruct(
+ $message, $boundary, $EOL = Zend_Mime::LINEEND
+ )
+ {
+ $parts = self::splitMime($message, $boundary);
+ if (count($parts) <= 0) {
+ return null;
+ }
+ $result = array();
+ foreach ($parts as $part) {
+ self::splitMessage($part, $headers, $body, $EOL);
+ $result[] = array(
+ 'header' => $headers,
+ 'body' => $body
+ );
+ }
+
+ return $result;
+ }
+
+ /**
+ * split a message in header and body part, if no header or an
+ * invalid header is found $headers is empty
+ *
+ * The charset of the returned headers depend on your iconv settings.
+ *
+ * @param string $message raw message with header and optional content
+ * @param array $headers output param, array with headers as array(name => value)
+ * @param string $body output param, content of message
+ * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
+ * @return null
+ */
+ public static function splitMessage(
+ $message, &$headers, &$body, $EOL = Zend_Mime::LINEEND
+ )
+ {
+ // check for valid header at first line
+ $firstline = strtok($message, "\n");
+ if (!preg_match('%^[^\s]+[^:]*:%', $firstline)) {
+ $headers = array();
+ // TODO: we're ignoring \r for now - is this function fast enough and is it safe to asume noone needs \r?
+ $body = str_replace(
+ array(
+ "\r",
+ "\n"
+ ), array(
+ '',
+ $EOL
+ ), $message
+ );
+
+ return;
+ }
+
+ // find an empty line between headers and body
+ // default is set new line
+ if (strpos($message, $EOL . $EOL)) {
+ list($headers, $body) = explode($EOL . $EOL, $message, 2);
+ // next is the standard new line
+ } else {
+ if ($EOL != "\r\n" && strpos($message, "\r\n\r\n")) {
+ list($headers, $body) = explode("\r\n\r\n", $message, 2);
+ // next is the other "standard" new line
+ } else {
+ if ($EOL != "\n" && strpos($message, "\n\n")) {
+ list($headers, $body) = explode("\n\n", $message, 2);
+ // at last resort find anything that looks like a new line
+ } else {
+ @list($headers, $body) =
+ @preg_split("%([\r\n]+)\\1%U", $message, 2);
+ }
+ }
+ }
+
+ $headers = iconv_mime_decode_headers(
+ $headers, ICONV_MIME_DECODE_CONTINUE_ON_ERROR
+ );
+
+ if ($headers === false) {
+ // an error occurs during the decoding
+ return;
+ }
+
+ // normalize header names
+ foreach ($headers as $name => $header) {
+ $lower = strtolower($name);
+ if ($lower == $name) {
+ continue;
+ }
+ unset($headers[$name]);
+ if (!isset($headers[$lower])) {
+ $headers[$lower] = $header;
+ continue;
+ }
+ if (is_array($headers[$lower])) {
+ $headers[$lower][] = $header;
+ continue;
+ }
+ $headers[$lower] = array(
+ $headers[$lower],
+ $header
+ );
+ }
+ }
+
+ /**
+ * split a content type in its different parts
+ *
+ * @param string $type content-type
+ * @param string $wantedPart the wanted part, else an array with all parts is returned
+ * @return string|array wanted part or all parts as array('type' => content-type, partname => value)
+ */
+ public static function splitContentType($type, $wantedPart = null)
+ {
+ return self::splitHeaderField($type, $wantedPart, 'type');
+ }
+
+ /**
+ * split a header field like content type in its different parts
+ *
+ * @param string $field
+ * @param string $wantedPart the wanted part, else an array with all parts is returned
+ * @param int|string $firstName key name for the first part
+ * @throws Zend_Exception
+ * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value)
+ */
+ public static function splitHeaderField(
+ $field, $wantedPart = null, $firstName = 0
+ )
+ {
+ $wantedPart = strtolower($wantedPart);
+ $firstName = strtolower($firstName);
+
+ // special case - a bit optimized
+ if ($firstName === $wantedPart) {
+ $field = strtok($field, ';');
+
+ return $field[0] == '"' ? substr($field, 1, -1) : $field;
+ }
+
+ $field = $firstName . '=' . $field;
+ if (!preg_match_all('%([^=\s]+)\s*=\s*("[^"]+"|[^;]+)(;\s*|$)%', $field, $matches)) {
+ throw new Zend_Exception('not a valid header field');
+ }
+
+ if ($wantedPart) {
+ foreach ($matches[1] as $key => $name) {
+ if (strcasecmp($name, $wantedPart)) {
+ continue;
+ }
+ if ($matches[2][$key][0] != '"') {
+ return $matches[2][$key];
+ }
+
+ return substr($matches[2][$key], 1, -1);
+ }
+
+ return null;
+ }
+
+ $split = array();
+ foreach ($matches[1] as $key => $name) {
+ $name = strtolower($name);
+ if ($matches[2][$key][0] == '"') {
+ $split[$name] = substr($matches[2][$key], 1, -1);
+ } else {
+ $split[$name] = $matches[2][$key];
+ }
+ }
+
+ return $split;
+ }
+
+ /**
+ * decode a quoted printable encoded string
+ *
+ * The charset of the returned string depends on your iconv settings.
+ *
+ * @param string $string Encoded string
+ * @return string Decoded string
+ */
+ public static function decodeQuotedPrintable($string)
+ {
+ return quoted_printable_decode($string);
+ }
+}
diff --git a/library/vendor/Zend/Mime/Exception.php b/library/vendor/Zend/Mime/Exception.php
new file mode 100644
index 0000000..a803058
--- /dev/null
+++ b/library/vendor/Zend/Mime/Exception.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Mime
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Exception
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Mime
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Mime_Exception extends Zend_Exception
+{
+}
+
diff --git a/library/vendor/Zend/Mime/Message.php b/library/vendor/Zend/Mime/Message.php
new file mode 100644
index 0000000..6082890
--- /dev/null
+++ b/library/vendor/Zend/Mime/Message.php
@@ -0,0 +1,302 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Mime
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Mime
+ */
+
+/**
+ * Zend_Mime_Part
+ */
+
+/**
+ * @category Zend
+ * @package Zend_Mime
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Mime_Message
+{
+ /**
+ * The Zend_Mime_Parts of the message
+ *
+ * @var array
+ */
+ protected $_parts = array();
+
+ /**
+ * The Zend_Mime object for the message
+ *
+ * @var Zend_Mime|null
+ */
+ protected $_mime = null;
+
+ /**
+ * Returns the list of all Zend_Mime_Parts in the message
+ *
+ * @return array of Zend_Mime_Part
+ */
+ public function getParts()
+ {
+ return $this->_parts;
+ }
+
+ /**
+ * Sets the given array of Zend_Mime_Parts as the array for the message
+ *
+ * @param array $parts
+ */
+ public function setParts($parts)
+ {
+ $this->_parts = $parts;
+ }
+
+ /**
+ * Append a new Zend_Mime_Part to the current message
+ *
+ * @param Zend_Mime_Part $part
+ */
+ public function addPart(Zend_Mime_Part $part)
+ {
+ /**
+ * @todo check for duplicate object handle
+ */
+ $this->_parts[] = $part;
+ }
+
+ /**
+ * Check if message needs to be sent as multipart
+ * MIME message or if it has only one part.
+ *
+ * @return boolean
+ */
+ public function isMultiPart()
+ {
+ return (count($this->_parts) > 1);
+ }
+
+ /**
+ * Set Zend_Mime object for the message
+ *
+ * This can be used to set the boundary specifically or to use a subclass of
+ * Zend_Mime for generating the boundary.
+ *
+ * @param Zend_Mime $mime
+ */
+ public function setMime(Zend_Mime $mime)
+ {
+ $this->_mime = $mime;
+ }
+
+ /**
+ * Returns the Zend_Mime object in use by the message
+ *
+ * If the object was not present, it is created and returned. Can be used to
+ * determine the boundary used in this message.
+ *
+ * @return Zend_Mime
+ */
+ public function getMime()
+ {
+ if ($this->_mime === null) {
+ $this->_mime = new Zend_Mime();
+ }
+
+ return $this->_mime;
+ }
+
+ /**
+ * Generate MIME-compliant message from the current configuration
+ *
+ * This can be a multipart message if more than one MIME part was added. If
+ * only one part is present, the content of this part is returned. If no
+ * part had been added, an empty string is returned.
+ *
+ * Parts are seperated by the mime boundary as defined in Zend_Mime. If
+ * {@link setMime()} has been called before this method, the Zend_Mime
+ * object set by this call will be used. Otherwise, a new Zend_Mime object
+ * is generated and used.
+ *
+ * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
+ * @return string
+ */
+ public function generateMessage($EOL = Zend_Mime::LINEEND)
+ {
+ if (!$this->isMultiPart()) {
+ $body = array_shift($this->_parts);
+ $body = $body->getContent($EOL);
+ } else {
+ $mime = $this->getMime();
+
+ $boundaryLine = $mime->boundaryLine($EOL);
+ $body = 'This is a message in Mime Format. If you see this, '
+ . "your mail reader does not support this format." . $EOL;
+
+ foreach (array_keys($this->_parts) as $p) {
+ $body .= $boundaryLine
+ . $this->getPartHeaders($p, $EOL)
+ . $EOL
+ . $this->getPartContent($p, $EOL);
+ }
+
+ $body .= $mime->mimeEnd($EOL);
+ }
+
+ return trim($body);
+ }
+
+ /**
+ * Get the headers of a given part as an array
+ *
+ * @param int $partnum
+ * @return array
+ */
+ public function getPartHeadersArray($partnum)
+ {
+ return $this->_parts[$partnum]->getHeadersArray();
+ }
+
+ /**
+ * Get the headers of a given part as a string
+ *
+ * @param int $partnum
+ * @param string $EOL
+ * @return string
+ */
+ public function getPartHeaders($partnum, $EOL = Zend_Mime::LINEEND)
+ {
+ return $this->_parts[$partnum]->getHeaders($EOL);
+ }
+
+ /**
+ * Get the (encoded) content of a given part as a string
+ *
+ * @param int $partnum
+ * @param string $EOL
+ * @return string
+ */
+ public function getPartContent($partnum, $EOL = Zend_Mime::LINEEND)
+ {
+ return $this->_parts[$partnum]->getContent($EOL);
+ }
+
+ /**
+ * Explode MIME multipart string into seperate parts
+ *
+ * Parts consist of the header and the body of each MIME part.
+ *
+ * @param string $body
+ * @param string $boundary
+ * @throws Zend_Exception
+ * @return array
+ */
+ protected static function _disassembleMime($body, $boundary)
+ {
+ $start = 0;
+ $res = array();
+ // find every mime part limiter and cut out the
+ // string before it.
+ // the part before the first boundary string is discarded:
+ $p = strpos($body, '--' . $boundary . "\n", $start);
+ if ($p === false) {
+ // no parts found!
+ return array();
+ }
+
+ // position after first boundary line
+ $start = $p + 3 + strlen($boundary);
+
+ while (($p = strpos($body, '--' . $boundary . "\n", $start))
+ !== false) {
+ $res[] = substr($body, $start, $p - $start);
+ $start = $p + 3 + strlen($boundary);
+ }
+
+ // no more parts, find end boundary
+ $p = strpos($body, '--' . $boundary . '--', $start);
+ if ($p === false) {
+ throw new Zend_Exception('Not a valid Mime Message: End Missing');
+ }
+
+ // the remaining part also needs to be parsed:
+ $res[] = substr($body, $start, $p - $start);
+
+ return $res;
+ }
+
+ /**
+ * Decodes a MIME encoded string and returns a Zend_Mime_Message object with
+ * all the MIME parts set according to the given string
+ *
+ * @param string $message
+ * @param string $boundary
+ * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND}
+ * @throws Zend_Exception
+ * @return Zend_Mime_Message
+ */
+ public static function createFromMessage(
+ $message, $boundary, $EOL = Zend_Mime::LINEEND
+ )
+ {
+ $parts = Zend_Mime_Decode::splitMessageStruct($message, $boundary, $EOL);
+
+ $res = new self();
+ foreach ($parts as $part) {
+ // now we build a new MimePart for the current Message Part:
+ $newPart = new Zend_Mime_Part($part['body']);
+ foreach ($part['header'] as $key => $value) {
+ /**
+ * @todo check for characterset and filename
+ */
+ switch (strtolower($key)) {
+ case 'content-type':
+ $newPart->type = $value;
+ break;
+ case 'content-transfer-encoding':
+ $newPart->encoding = $value;
+ break;
+ case 'content-id':
+ $newPart->id = trim($value, '<>');
+ break;
+ case 'content-disposition':
+ $newPart->disposition = $value;
+ break;
+ case 'content-description':
+ $newPart->description = $value;
+ break;
+ case 'content-location':
+ $newPart->location = $value;
+ break;
+ case 'content-language':
+ $newPart->language = $value;
+ break;
+ default:
+ throw new Zend_Exception(
+ 'Unknown header ignored for MimePart:' . $key
+ );
+ }
+ }
+ $res->addPart($newPart);
+ }
+
+ return $res;
+ }
+}
diff --git a/library/vendor/Zend/Mime/Part.php b/library/vendor/Zend/Mime/Part.php
new file mode 100644
index 0000000..852fb56
--- /dev/null
+++ b/library/vendor/Zend/Mime/Part.php
@@ -0,0 +1,329 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category Zend
+ * @package Zend_Mime
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ * @version $Id$
+ */
+
+/**
+ * Zend_Mime
+ */
+
+/**
+ * Class representing a MIME part.
+ *
+ * @category Zend
+ * @package Zend_Mime
+ * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+class Zend_Mime_Part
+{
+
+ /**
+ * Type
+ *
+ * @var string
+ */
+ public $type = Zend_Mime::TYPE_OCTETSTREAM;
+
+ /**
+ * Encoding
+ *
+ * @var string
+ */
+ public $encoding = Zend_Mime::ENCODING_8BIT;
+
+ /**
+ * ID
+ *
+ * @var string
+ */
+ public $id;
+
+ /**
+ * Disposition
+ *
+ * @var string
+ */
+ public $disposition;
+
+ /**
+ * Filename
+ *
+ * @var string
+ */
+ public $filename;
+
+ /**
+ * Description
+ *
+ * @var string
+ */
+ public $description;
+
+ /**
+ * Character set
+ *
+ * @var string
+ */
+ public $charset;
+
+ /**
+ * Boundary
+ *
+ * @var string
+ */
+ public $boundary;
+
+ /**
+ * Location
+ *
+ * @var string
+ */
+ public $location;
+
+ /**
+ * Language
+ *
+ * @var string
+ */
+ public $language;
+
+ /**
+ * Content
+ *
+ * @var mixed
+ */
+ protected $_content;
+
+ /**
+ * @var bool
+ */
+ protected $_isStream = false;
+
+ /**
+ * create a new Mime Part.
+ * The (unencoded) content of the Part as passed
+ * as a string or stream
+ *
+ * @param mixed $content String or Stream containing the content
+ */
+ public function __construct($content)
+ {
+ $this->_content = $content;
+ if (is_resource($content)) {
+ $this->_isStream = true;
+ }
+ }
+
+ /**
+ * @todo setters/getters
+ * @todo error checking for setting $type
+ * @todo error checking for setting $encoding
+ */
+
+ /**
+ * check if this part can be read as a stream.
+ * if true, getEncodedStream can be called, otherwise
+ * only getContent can be used to fetch the encoded
+ * content of the part
+ *
+ * @return bool
+ */
+ public function isStream()
+ {
+ return $this->_isStream;
+ }
+
+ /**
+ * if this was created with a stream, return a filtered stream for
+ * reading the content. very useful for large file attachments.
+ *
+ * @return mixed Stream
+ * @throws Zend_Mime_Exception if not a stream or unable to append filter
+ */
+ public function getEncodedStream()
+ {
+ if (!$this->_isStream) {
+ throw new Zend_Mime_Exception(
+ 'Attempt to get a stream from a string part'
+ );
+ }
+
+ //stream_filter_remove(); // ??? is that right?
+ switch ($this->encoding) {
+ case Zend_Mime::ENCODING_QUOTEDPRINTABLE:
+ $filter = stream_filter_append(
+ $this->_content,
+ 'convert.quoted-printable-encode',
+ STREAM_FILTER_READ,
+ array(
+ 'line-length' => 76,
+ 'line-break-chars' => Zend_Mime::LINEEND
+ )
+ );
+ if (!is_resource($filter)) {
+ throw new Zend_Mime_Exception(
+ 'Failed to append quoted-printable filter'
+ );
+ }
+ break;
+
+ case Zend_Mime::ENCODING_BASE64:
+ $filter = stream_filter_append(
+ $this->_content,
+ 'convert.base64-encode',
+ STREAM_FILTER_READ,
+ array(
+ 'line-length' => 76,
+ 'line-break-chars' => Zend_Mime::LINEEND
+ )
+ );
+ if (!is_resource($filter)) {
+ throw new Zend_Mime_Exception(
+ 'Failed to append base64 filter'
+ );
+ }
+ break;
+
+ default:
+ }
+
+ return $this->_content;
+ }
+
+ /**
+ * Get the Content of the current Mime Part in the given encoding.
+ *
+ * @param string $EOL Line end; defaults to {@link Zend_Mime::LINEEND}
+ * @throws Zend_Mime_Exception
+ * @return string
+ */
+ public function getContent($EOL = Zend_Mime::LINEEND)
+ {
+ if ($this->_isStream) {
+ return stream_get_contents($this->getEncodedStream());
+ } else {
+ return Zend_Mime::encode($this->_content, $this->encoding, $EOL);
+ }
+ }
+
+ /**
+ * Get the RAW unencoded content from this part
+ *
+ * @return string
+ */
+ public function getRawContent()
+ {
+ if ($this->_isStream) {
+ return stream_get_contents($this->_content);
+ } else {
+ return $this->_content;
+ }
+ }
+
+ /**
+ * Create and return the array of headers for this MIME part
+ *
+ * @param string $EOL Line end; defaults to {@link Zend_Mime::LINEEND}
+ * @return array
+ */
+ public function getHeadersArray($EOL = Zend_Mime::LINEEND)
+ {
+ $headers = array();
+
+ $contentType = $this->type;
+ if ($this->charset) {
+ $contentType .= '; charset=' . $this->charset;
+ }
+
+ if ($this->boundary) {
+ $contentType .= ';' . $EOL
+ . " boundary=\"" . $this->boundary . '"';
+ }
+
+ $headers[] = array(
+ 'Content-Type',
+ $contentType
+ );
+
+ if ($this->encoding) {
+ $headers[] = array(
+ 'Content-Transfer-Encoding',
+ $this->encoding
+ );
+ }
+
+ if ($this->id) {
+ $headers[] = array(
+ 'Content-ID',
+ '<' . $this->id . '>'
+ );
+ }
+
+ if ($this->disposition) {
+ $disposition = $this->disposition;
+ if ($this->filename) {
+ $disposition .= '; filename="' . $this->filename . '"';
+ }
+ $headers[] = array(
+ 'Content-Disposition',
+ $disposition
+ );
+ }
+
+ if ($this->description) {
+ $headers[] = array(
+ 'Content-Description',
+ $this->description
+ );
+ }
+
+ if ($this->location) {
+ $headers[] = array(
+ 'Content-Location',
+ $this->location
+ );
+ }
+
+ if ($this->language) {
+ $headers[] = array(
+ 'Content-Language',
+ $this->language
+ );
+ }
+
+ return $headers;
+ }
+
+ /**
+ * Return the headers for this part as a string
+ *
+ * @param string $EOL Line end; defaults to {@link Zend_Mime::LINEEND}
+ * @return string
+ */
+ public function getHeaders($EOL = Zend_Mime::LINEEND)
+ {
+ $res = '';
+ foreach ($this->getHeadersArray($EOL) as $header) {
+ $res .= $header[0] . ': ' . $header[1] . $EOL;
+ }
+
+ return $res;
+ }
+}