summaryrefslogtreecommitdiff
path: root/program/include
diff options
context:
space:
mode:
authoralecpl <alec@alec.pl>2010-04-01 13:42:39 +0000
committeralecpl <alec@alec.pl>2010-04-01 13:42:39 +0000
commit70318e5463986edff014e881e7e121483679726b (patch)
tree1191259ee3c56f224b62604f4171baea1527fc23 /program/include
parent1820932295a2c4a8d7f716f540dbbe9327c7b28f (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.php23
-rw-r--r--program/include/rcube_mime_struct.php209
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;
+ }
+
+
+}