Many fixes and optimisations:
[banana.git] / banana / mimepart.inc.php
index d90a22b..1ca1ec8 100644 (file)
@@ -160,14 +160,14 @@ class BananaMimePart
             $encoding     = '8bit';
             $charset      = 'CP1252';
             $content_type = 'text/plain';
-            $format       = strtolower($this->getHeader('x-rfc2646', '/format="?([^"]+?)"?\s*(;|$)/i'));
+            $format       = strtolower($this->getHeader('x-rfc2646', '/format="?([^ w@"]+?)"?\s*(;|$)/i'));
         } else {
             $encoding     = strtolower($this->getHeader('content-transfer-encoding'));
             $disposition  = $this->getHeader('content-disposition', '/(inline|attachment)/i');
-            $boundary     = $this->getHeader('content-type', '/boundary="?([^"]+?)"?\s*(;|$)/i');
-            $charset      = strtolower($this->getHeader('content-type', '/charset="?([^"]+?)"?\s*(;|$)/i'));
-            $filename     = $this->getHeader('content-disposition', '/filename="?([^"]+?)"?\s*(;|$)/i');
-            $format       = strtolower($this->getHeader('content-type', '/format="?([^"]+?)"?\s*(;|$)/i'));
+            $boundary     = $this->getHeader('content-type', '/boundary="?([^ "]+?)"?\s*(;|$)/i');
+            $charset      = strtolower($this->getHeader('content-type', '/charset="?([^ "]+?)"?\s*(;|$)/i'));
+            $filename     = $this->getHeader('content-disposition', '/filename="?([^ "]+?)"?\s*(;|$)/i');
+            $format       = strtolower($this->getHeader('content-type', '/format="?([^ "]+?)"?\s*(;|$)/i'));
             $id           = $this->getHeader('content-id', '/<(.*?)>/');
             if (empty($filename)) {
                 $filename = $this->getHeader('content-type', '/name="?([^"]+)"?/');
@@ -269,16 +269,16 @@ class BananaMimePart
     static public function &parseHeaders(array &$lines)
     {
         $headers = array();
-        while (count($lines)) {
+        while ($lines) {
             $line = array_shift($lines);
-            if (preg_match('/^[\t\r ]+/', $line) && isset($hdr)) {
+            if (isset($hdr) && $line && ctype_space($line{0})) {
                 $headers[$hdr] .= ' ' . trim($line);
             } elseif (!empty($line)) {
-                if (preg_match("/:[ \t\r]*/", $line)) {
-                    list($hdr, $val) = split(":[ \t\r]*", $line, 2);
+                if (strpos($line, ':') !== false) {
+                    list($hdr, $val) = explode(":", $line, 2);
                     $hdr = strtolower($hdr);
                     if (in_array($hdr, Banana::$msgparse_headers)) {  
-                        $headers[$hdr] = $val;
+                        $headers[$hdr] = ltrim($val);
                     } else {
                         unset($hdr);
                     }
@@ -388,8 +388,13 @@ class BananaMimePart
         $content = "";
         if ($with_headers) {
             foreach ($this->getHeaders() as $key => $value) {
-                $content .= "$key: $value\n"; 
-            }   
+                $line = "$key: $value"; 
+                $line = explode("\n", wordwrap($line, Banana::$msgshow_wrap));
+                for ($i = 1 ; $i < count($line) ; $i++) {
+                    $line[$i] = "\t" . $line[$i];
+                }
+                $content .= implode("\n", $line) . "\n";
+            } 
             $content .= "\n";
         } 
         if ($this->isType('multipart')) {
@@ -399,20 +404,83 @@ class BananaMimePart
             }
             $content .= "\n--{$this->boundary}--";
         } else {
-            $content .= $this->body;
+            $content .= banana_wordwrap($this->body);
         }
         return $content;
     }
 
     public function getText()
     {
-        if (!$this->isType('text')) {
-            return null;
-        }
         $this->decodeContent();
         return $this->body;
     }
 
+    public function toHtml()
+    {
+        list($type, $subtype) = $this->getType();
+        if ($type == 'image') {
+            $part = $this->id ? $this->id : $this->filename;
+            return '<img class="multipart" src="'
+                 . banana_htmlentities(Banana::$page->makeUrl(array('group' => Banana::$group,
+                                                                    'artid' => Banana::$artid,
+                                                                    'part'  => $part)))
+                 . '" alt="' . banana_htmlentities($this->filename) . '" />';
+        } elseif (!in_array($type, Banana::$msgshow_mimeparts)
+                  && !in_array($this->content_type, Banana::$msgshow_mimeparts)) {
+            $part = $this->id ? $this->id : $this->filename;
+            if (!$part) {
+                $part = $this->content_type;
+            }
+            return '[' . Banana::$page->makeImgLink(array('group' => Banana::$group,
+                                                 'artid' => Banana::$artid,
+                                                 'part'  => $part,
+                                                 'text'  => $this->filename ? $this->filename : $this->content_type,
+                                                 'img'   => 'save')) . ']';
+        } else {
+            if ($type == 'multipart' && ($subtype == 'mixed' || $subtype == 'report')) {
+                $text = '';
+                foreach ($this->multipart as &$part) {
+                    $text .= $part->toHtml();
+                }
+                return $text;
+            }
+            switch ($subtype) {
+              case 'html': return banana_formatHtml($this);
+              case 'enriched': case 'richtext': return banana_formatRichText($this);
+              default:
+                if ($type == 'message') { // we have a raw source of data (no specific pre-formatting)
+                    return '<hr />' . utf8_encode(banana_formatPlainText($this));
+                }
+                return banana_formatPlainText($this);
+            }
+        }
+        return null;
+    }
+
+    public function quote()
+    {
+        list($type, $subtype) = $this->getType();
+        if (in_array($type, Banana::$msgedit_mimeparts) || in_array($this->content_type, Banana::$msgedit_mimeparts)) {
+            if ($type == 'multipart' && ($subtype == 'mixed' || $subtype == 'report')) {
+                $text = '';
+                foreach ($this->multipart as &$part) {
+                    $qt = $part->quote();
+                    $qt = rtrim($qt);
+                    if (!empty($text)) {
+                        $text .= "\n" . banana_quote("", 1) . "\n";
+                    }
+                    $text .= $qt;
+                }
+                return $text;
+            }
+            switch ($subtype) {
+              case 'html': return banana_quoteHtml($this);
+              case 'enriched': case 'richtext': return banana_quoteRichText($this);
+              default: return banana_quotePlainText($this);
+            }
+        }
+    }
+
     protected function getType()
     {
         return explode('/', $this->content_type);
@@ -447,24 +515,6 @@ class BananaMimePart
         return $parts;
     }
 
-    public function toPlainText()
-    {
-        $parts = $this->getParts('text', 'plain');
-        return (count($parts) ? $parts[0] : null);
-    }
-
-    public function toHtml()
-    {
-        $parts = $this->getParts('text', 'html');
-        return (count($parts) ? $parts[0] : null);
-    }
-
-    public function toRichText()
-    {
-        $parts = $this->getParts('text', 'enriched');
-        return (count($parts) ? $parts[0] : null);
-    }
-
     public function getFile($filename)
     {
         if ($this->filename == $filename) {
@@ -494,6 +544,43 @@ class BananaMimePart
         return array();
     }
 
+    public function getAlternatives()
+    {
+        $types =& Banana::$msgshow_mimeparts;
+        $names =& Banana::$mimeparts;
+        $source = null;
+        if (in_array('source', $types)) {
+            $source = @$names['source'] ? $names['source'] : 'source';
+        }
+        if (!$this->isType('multipart', 'alternative') && !$this->isType('multipart', 'related')) {
+            if ($source) {
+                $parts = array($this);
+            } else {
+                return array();
+            }
+        } else {
+            $parts =& $this->multipart;
+        }
+        $alt = array();
+        foreach ($parts as &$part) {
+            list($type, $subtype) = $part->getType();
+            $ct = $type . '/' . $subtype;
+            if (in_array($ct, $types) || in_array($type, $types)) {
+                if (isset($names[$ct])) {
+                    $alt[$ct] = $names[$ct];
+                } elseif (isset($names[$type])) {
+                    $alt[$ct] = $names[$type];
+                } else {
+                    $alt[$ct] = $ct;
+                }
+            }
+        }
+        if ($source) {
+            $alt['source'] = $source;
+        }
+        return $alt;
+    }
+
     public function getPartById($id)
     {
         if ($this->id == $id) {
@@ -510,5 +597,5 @@ class BananaMimePart
     }
 }
 
-// vim:set et sw=4 sts=4 ts=4:
+// vim:set et sw=4 sts=4 ts=4 enc=utf-8:
 ?>