diff options
author | alecpl <alec@alec.pl> | 2010-04-01 13:42:39 +0000 |
---|---|---|
committer | alecpl <alec@alec.pl> | 2010-04-01 13:42:39 +0000 |
commit | 70318e5463986edff014e881e7e121483679726b (patch) | |
tree | 1191259ee3c56f224b62604f4171baea1527fc23 /program/include | |
parent | 1820932295a2c4a8d7f716f540dbbe9327c7b28f (diff) |
- create rcube_mime_struct class on Iloha's MIME (mime.inc) basis
Diffstat (limited to 'program/include')
-rw-r--r-- | program/include/rcube_imap.php | 23 | ||||
-rw-r--r-- | program/include/rcube_mime_struct.php | 209 |
2 files changed, 220 insertions, 12 deletions
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 7dc70df32..22f497927 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -21,10 +21,6 @@ */ -require_once('lib/mime.inc'); -require_once('lib/tnef_decoder.inc'); - - /** * Interface class for accessing an IMAP server * @@ -1614,9 +1610,10 @@ class rcube_imap return $headers->structure; } - if (!$structure_str) + if (!$structure_str) { $structure_str = $this->conn->fetchStructureString($this->mailbox, $uid, true); - $structure = iml_GetRawStructureArray($structure_str); + } + $structure = rcube_mime_struct::parseStructure($structure_str); $struct = false; // parse structure and add headers @@ -1966,16 +1963,16 @@ class rcube_imap // get part encoding if not provided if (!is_object($o_part)) { $structure_str = $this->conn->fetchStructureString($this->mailbox, $uid, true); - $structure = iml_GetRawStructureArray($structure_str); + $structure = new rcube_mime_struct(); // error or message not found - if (empty($structure)) + if (!$structure->loadStructure($structure_str)) { return false; + } - $part_type = iml_GetPartTypeCode($structure, $part); $o_part = new rcube_message_part; - $o_part->ctype_primary = $part_type==0 ? 'text' : ($part_type==2 ? 'message' : 'other'); - $o_part->encoding = strtolower(iml_GetPartEncodingString($structure, $part)); - $o_part->charset = iml_GetPartCharset($structure, $part); + $o_part->ctype_primary = strtolower($structure->getPartType($part)); + $o_part->encoding = strtolower($structure->getPartEncoding($part)); + $o_part->charset = $structure->getPartCharset($part); } // TODO: Add caching for message parts @@ -3331,6 +3328,8 @@ class rcube_imap if (!isset($part->body)) $part->body = $this->get_message_part($uid, $part->mime_id, $part); + require_once('lib/tnef_decoder.inc'); + $pid = 0; $tnef_parts = array(); $tnef_arr = tnef_decode($part->body); diff --git a/program/include/rcube_mime_struct.php b/program/include/rcube_mime_struct.php new file mode 100644 index 000000000..bc00da50a --- /dev/null +++ b/program/include/rcube_mime_struct.php @@ -0,0 +1,209 @@ +<?php + + +/* + +-----------------------------------------------------------------------+ + | program/include/rcube_mime_struct.php | + | | + | This file is part of the RoundCube Webmail client | + | Copyright (C) 2005-2010, RoundCube Dev. - Switzerland | + | Licensed under the GNU GPL | + | | + | PURPOSE: | + | Provide functions for handling mime messages structure | + | | + | Based on Iloha MIME Library. See http://ilohamail.org/ for details | + | | + +-----------------------------------------------------------------------+ + | Author: Aleksander Machniak <alec@alec.pl> | + | Author: Ryo Chijiiwa <Ryo@IlohaMail.org> | + +-----------------------------------------------------------------------+ + + $Id$ + +*/ + + +class rcube_mime_struct +{ + private $structure; + + + function __construct($str=null) + { + if ($str) + $this->structure = $this->parseStructure($str); + } + + /* + * Parses IMAP's BODYSTRUCTURE string into array + */ + function parseStructure($str) + { + $line = substr($str, 1, strlen($str) - 2); + $line = str_replace(')(', ') (', $line); + + $struct = self::parseBSString($line); + if (!is_array($struct[0]) && (strcasecmp($struct[0], 'message') == 0) + && (strcasecmp($struct[1], 'rfc822') == 0)) { + $struct = array($struct); + } + + return $struct; + } + + /* + * Parses IMAP's BODYSTRUCTURE string into array and loads it into class internal variable + */ + function loadStructure($str) + { + if (empty($str)) + return true; + + $this->structure = $this->parseStructure($str); + return (!empty($this->structure)); + } + + function getPartType($part) + { + $part_a = $this->getPartArray($this->structure, $part); + if (!empty($part_a)) { + if (is_array($part_a[0])) + return 'multipart'; + else if ($part_a[0]) + return $part_a[0]; + } + + return 'other'; + } + + function getPartEncoding($part) + { + $part_a = $this->getPartArray($this->structure, $part); + if ($part_a) { + if (!is_array($part_a[0])) + return $part_a[5]; + } + + return ''; + } + + function getPartCharset($part) + { + $part_a = $this->getPartArray($this->structure, $part); + if ($part_a) { + if (is_array($part_a[0])) + return ''; + else { + if (is_array($part_a[2])) { + $name = ''; + while (list($key, $val) = each($part_a[2])) + if (strcasecmp($val, 'charset') == 0) + return $part_a[2][$key+1]; + } + } + } + + return ''; + } + + function getPartArray($a, $part) + { + if (!is_array($a)) { + return false; + } + if (strpos($part, '.') > 0) { + $original_part = $part; + $pos = strpos($part, '.'); + $rest = substr($original_part, $pos+1); + $part = substr($original_part, 0, $pos); + if ((strcasecmp($a[0], 'message') == 0) && (strcasecmp($a[1], 'rfc822') == 0)) { + $a = $a[8]; + } + return self::getPartArray($a[$part-1], $rest); + } + else if ($part>0) { + if (!is_array($a[0]) && (strcasecmp($a[0], 'message') == 0) + && (strcasecmp($a[1], 'rfc822') == 0)) { + $a = $a[8]; + } + if (is_array($a[$part-1])) + return $a[$part-1]; + else + return $a; + } + else if (($part==0) || (empty($part))) { + return $a; + } + } + + private function closingParenPos($str, $start) + { + $level = 0; + $len = strlen($str); + $in_quote = 0; + + for ($i=$start; $i<$len; $i++) { + if ($str[$i] == '"' && $str[$i-1] != "\\") { + $in_quote = ($in_quote + 1) % 2; + } + if (!$in_quote) { + if ($str[$i] == '(') + $level++; + else if (($level > 0) && ($str[$i] == ')')) + $level--; + else if (($level == 0) && ($str[$i] == ')')) + return $i; + } + } + } + + /* + * Parses IMAP's BODYSTRUCTURE string into array + */ + private function parseBSString($str) + { + $id = 0; + $a = array(); + $len = strlen($str); + $in_quote = 0; + + for ($i=0; $i<$len; $i++) { + if ($str[$i] == '"') { + $in_quote = ($in_quote + 1) % 2; + } else if (!$in_quote) { + // space means new element + if ($str[$i] == ' ') { + $id++; + // skip additional spaces + while ($str[$i+1] == ' ') + $i++; + // new part + } else if ($str[$i] == '(') { + $i++; + $endPos = self::closingParenPos($str, $i); + $partLen = $endPos - $i; + if ($partLen < 0) + break; + $part = substr($str, $i, $partLen); + $a[$id] = self::parseBSString($part); // send part string + $i = $endPos; + } else + $a[$id] .= $str[$i]; //add to current element in array + } else if ($in_quote) { + if ($str[$i] == "\\") { + $i++; // escape backslashes + if ($str[$i] == '"' || $str[$i] == "\\") + $a[$id] .= $str[$i]; + } + else + $a[$id] .= $str[$i]; //add to current element in array + } + } + + reset($a); + return $a; + } + + +} |