diff options
Diffstat (limited to 'applications/core/lib/Zend/Mime/Decode.php')
| -rw-r--r-- | applications/core/lib/Zend/Mime/Decode.php | 243 | 
1 files changed, 243 insertions, 0 deletions
| diff --git a/applications/core/lib/Zend/Mime/Decode.php b/applications/core/lib/Zend/Mime/Decode.php new file mode 100644 index 0000000..cc4de8b --- /dev/null +++ b/applications/core/lib/Zend/Mime/Decode.php @@ -0,0 +1,243 @@ +<?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 [email protected] so we can send you a copy immediately. + * + * @category   Zend + * @package    Zend_Mime + * @copyright  Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com) + * @license    http://framework.zend.com/license/new-bsd     New BSD License + */ + +/** + * @see Zend_Mime + */ +require_once 'Zend/Mime.php'; + +/** + * @category   Zend + * @package    Zend_Mime + * @copyright  Copyright (c) 2005-2008 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 $type       header field +     * @param  string $wantedPart the wanted part, else an array with all parts is returned +     * @param  string $firstName  key name for the first part +     * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value) +     * @throws Zend_Exception +     */ +    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 encoded string +     * @return string decoded string +     */ +    public static function decodeQuotedPrintable($string) +    { +        return iconv_mime_decode($string, ICONV_MIME_DECODE_CONTINUE_ON_ERROR); +    } +} | 
