From 70318e5463986edff014e881e7e121483679726b Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Thu, 01 Apr 2010 09:42:39 -0400
Subject: [PATCH] - create rcube_mime_struct class on Iloha's MIME (mime.inc) basis

---
 /dev/null                             |  330 ---------------------------------
 program/include/rcube_imap.php        |   23 +-
 program/include/rcube_mime_struct.php |  209 ++++++++++++++++++++
 3 files changed, 220 insertions(+), 342 deletions(-)

diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 7dc70df..22f4979 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 @@
             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 @@
         // 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 @@
         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 0000000..bc00da5
--- /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;
+    }
+
+
+}
diff --git a/program/lib/mime.inc b/program/lib/mime.inc
deleted file mode 100644
index cb4f728..0000000
--- a/program/lib/mime.inc
+++ /dev/null
@@ -1,330 +0,0 @@
-<?php
-/////////////////////////////////////////////////////////
-//	
-//	Iloha MIME Library (IML)
-//
-//	(C)Copyright 2002 Ryo Chijiiwa <Ryo@IlohaMail.org>
-//
-//	This file is part of IlohaMail. IlohaMail is free software released 
-//	under the GPL license.  See enclosed file COPYING for details, or 
-//	see http://www.fsf.org/copyleft/gpl.html
-//
-/////////////////////////////////////////////////////////
-
-/********************************************************
-
-	FILE: include/mime.inc
-	PURPOSE:
-		Provide functions for handling mime messages.
-	USAGE:
-		Use iil_C_FetchStructureString to get IMAP structure stirng, then pass that through
-		iml_GetRawStructureArray() to get root node to a nested data structure.
-		Pass root node to the iml_GetPart*() functions to retreive individual bits of info.
-
-********************************************************/
-$MIME_INVALID = -1;
-$MIME_TEXT = 0;
-$MIME_MULTIPART = 1;
-$MIME_MESSAGE = 2;
-$MIME_APPLICATION = 3;
-$MIME_AUDIO = 4;
-$MIME_IMAGE = 5;
-$MIME_VIDEO = 6;
-$MIME_OTHER = 7;
-
-function iml_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;
-    	}
-    }
-}
-
-function iml_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) {
-            if ($str[$i] == " ") { //space means new element
-                $id++;
-                while ($str[$i+1] == " ") $i++;  // skip additional spaces
-            } else if ($str[$i]=="(") { //new part
-                $i++;
-                $endPos = iml_ClosingParenPos($str, $i);
-                $partLen = $endPos - $i;
-                if ($partLen < 0) break;
-                $part = substr($str, $i, $partLen);
-                $a[$id] = iml_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;
-}
-
-function iml_GetRawStructureArray($str){
-    $line=substr($str, 1, strlen($str) - 2);
-    $line = str_replace(")(", ") (", $line);
-
-	$struct = iml_ParseBSString($line);
-	if (!is_array($struct[0]) && (strcasecmp($struct[0], "message")==0)
-		&& (strcasecmp($struct[1], "rfc822")==0)) {
-		$struct = array($struct);
-	}
-    return $struct;
-}
-
-function iml_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];
-		}
-		//echo "m - part: $original_part current: $part rest: $rest array: ".implode(" ", $a)."<br>\n";
-		return iml_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];
-		}
-		//echo "s - part: $part rest: $rest array: ".implode(" ", $a)."<br>\n";
-		if (is_array($a[$part-1])) return $a[$part-1];
-		else return $a;
-	}else if (($part==0) || (empty($part))){
-		return $a;
-	}
-}
-
-function iml_GetNumParts($a, $part){
-	if (is_array($a)){
-		$parent=iml_GetPartArray($a, $part);
-		
-		if ((strcasecmp($parent[0], "message")==0) && (strcasecmp($parent[1], "rfc822")==0)){
-			$parent = $parent[8];
-		}
-
-		$is_array=true;
-		$c=0;
-		while (( list ($key, $val) = each ($parent) )&&($is_array)){
-			$is_array=is_array($parent[$key]);
-			if ($is_array) $c++;
-		}
-		return $c;
-	}
-	
-	return false;
-}
-
-function iml_GetPartTypeString($a, $part){
-	$part_a=iml_GetPartArray($a, $part);
-	if ($part_a){
-		if (is_array($part_a[0])){
-			$type_str = "MULTIPART/";
-			reset($part_a);
-			while(list($n,$element)=each($part_a)){
-				if (!is_array($part_a[$n])){
-					$type_str.=$part_a[$n];
-					break;
-				}
-			}
-			return $type_str;
-		}else return $part_a[0]."/".$part_a[1];
-	}else return false;
-}
-
-function iml_GetFirstTextPart($structure,$part){
-    if ($part==0) $part="";
-    $typeCode = -1;
-    while ($typeCode!=0){
-        $typeCode = iml_GetPartTypeCode($structure, $part);
-        if ($typeCode == 1){
-            $part .= (empty($part)?"":".")."1";
-        }else if ($typeCode > 0){
-            $parts_a = explode(".", $part);
-            $lastPart = count($parts_a) - 1;
-            $parts_a[$lastPart] = (int)$parts_a[$lastPart] + 1;
-            $part = implode(".", $parts_a);
-        }else if ($typeCode == -1){
-            return "";
-        }
-    }
-    
-    return $part;
-}
-
-function iml_GetPartTypeCode($a, $part){
-	$types=array(0=>"text",1=>"multipart",2=>"message",3=>"application",4=>"audio",5=>"image",6=>"video",7=>"other");
-
-	$part_a=iml_GetPartArray($a, $part);
-	if ($part_a){
-		if (is_array($part_a[0])) $str="multipart";
-		else $str=$part_a[0];
-
-		$code=7;
-		while ( list($key, $val) = each($types)) if (strcasecmp($val, $str)==0) $code=$key;
-		return $code;
-	}else return -1;
-}
-
-function iml_GetPartEncodingCode($a, $part){
-	$encodings=array("7BIT", "8BIT", "BINARY", "BASE64", "QUOTED-PRINTABLE", "OTHER");
-
-	$part_a=iml_GetPartArray($a, $part);
-	if ($part_a){
-		if (is_array($part_a[0])) return -1;
-		else $str=$part_a[5];
-
-		$code=5;
-		while ( list($key, $val) = each($encodings)) if (strcasecmp($val, $str)==0) $code=$key;
-
-		return $code;
-
-	}else return -1;
-}
-
-function iml_GetPartEncodingString($a, $part){
-	$part_a=iml_GetPartArray($a, $part);
-	if ($part_a){
-		if (is_array($part_a[0])) return -1;
-		else return $part_a[5];
-	}else return -1;
-}
-
-function iml_GetPartSize($a, $part){
-	$part_a=iml_GetPartArray($a, $part);
-	if ($part_a){
-		if (is_array($part_a[0])) return -1;
-		else return $part_a[6];
-	}else return -1;
-}
-
-function iml_GetPartID($a, $part){
-	$part_a=iml_GetPartArray($a, $part);
-	if ($part_a){
-		if (is_array($part_a[0])) return -1;
-		else return $part_a[3];
-	}else return -1;
-}
-
-function iml_GetPartDisposition($a, $part){
-	$part_a=iml_GetPartArray($a, $part);
-	if ($part_a){
-		if (is_array($part_a[0])) return -1;
-		else{
-            $id = count($part_a) - 2;
-			if (is_array($part_a[$id])) return $part_a[$id][0];
-			else return "";
-		}
-	}else return "";
-}
-
-function iml_GetPartName($a, $part){
-	$part_a=iml_GetPartArray($a, $part);
-	if ($part_a){
-		if (is_array($part_a[0])) return -1;
-		else{
-            $name = "";
-			if (is_array($part_a[2])){
-                //first look in content type
-				$name="";
-				while ( list($key, $val) = each ($part_a[2])){
-                    if ((strcasecmp($val, "NAME")==0)||(strcasecmp($val, "FILENAME")==0)) 
-                        $name=$part_a[2][$key+1];
-                }
-			}
-            if (empty($name)){
-                //check in content disposition
-                $id = count($part_a) - 2;
-                if ((is_array($part_a[$id])) && (is_array($part_a[$id][1]))){
-                    $array = $part_a[$id][1];
-                    while ( list($key, $val) = each($array)){
-                        if ((strcasecmp($val, "NAME")==0)||(strcasecmp($val, "FILENAME")==0)) 
-                            $name=$array[$key+1];
-                    }
-                }
-            }
-			return $name;
-		}
-	}else return "";
-}
-
-
-function iml_GetPartCharset($a, $part){
-	$part_a=iml_GetPartArray($a, $part);
-	if ($part_a){
-		if (is_array($part_a[0])) return -1;
-		else{
-			if (is_array($part_a[2])){
-				$name="";
-				while ( list($key, $val) = each ($part_a[2])) if (strcasecmp($val, "charset")==0) $name=$part_a[2][$key+1];
-				return $name;
-			}
-			else return "";
-		}
-	}else return "";
-}
-
-function iml_GetPartList($a, $part){
-	//echo "MOO?"; flush();
-	$data = array();
-	$num_parts = iml_GetNumParts($a, $part);
-	//echo "($num_parts)"; flush();
-	if ($num_parts !== false){
-		//echo "<!-- ($num_parts parts)//-->\n";
-		for ($i = 0; $i<$num_parts; $i++){
-			$part_code = $part.(empty($part)?"":".").($i+1);
-			$part_type = iml_GetPartTypeCode($a, $part_code);
-			$part_disposition = iml_GetPartDisposition($a, $part_code);
-			//echo "<!-- part: $part_code type: $part_type //-->\n";
-			if (strcasecmp($part_disposition, "attachment")!=0 && 
-				(($part_type == 1) || ($part_type==2))){
-				$data = array_merge($data, iml_GetPartList($a, $part_code));
-			}else{
-				$data[$part_code]["typestring"] = iml_GetPartTypeString($a, $part_code);
-				$data[$part_code]["disposition"] = $part_disposition;
-				$data[$part_code]["size"] = iml_GetPartSize($a, $part_code);
-				$data[$part_code]["name"] = iml_GetPartName($a, $part_code);
-				$data[$part_code]["id"] = iml_GetPartID($a, $part_code);
-			}
-		}
-	}
-	return $data;
-}
-
-function iml_GetNextPart($part){
-	if (strpos($part, ".")===false) return $part++;
-	else{
-		$parts_a = explode(".", $part);
-		$num_levels = count($parts_a);
-		$parts_a[$num_levels-1]++;
-		return implode(".", $parts_a);
-	}
-}
-?>
\ No newline at end of file

--
Gitblit v1.9.1