From a8a72e2e7ee89caa04f8f13b6067e1b4ad870612 Mon Sep 17 00:00:00 2001
From: Thomas Bruederli <thomas@roundcube.net>
Date: Mon, 10 Dec 2012 16:26:45 -0500
Subject: [PATCH] Nicely render headers of message/rfc822 parts

---
 skins/classic/mail.css                         |   11 +++++
 skins/larry/templates/message.html             |    2 
 program/steps/mail/func.inc                    |   31 +++++++++++----
 program/lib/Roundcube/rcube_message.php        |    9 ++++
 program/lib/Roundcube/rcube_message_header.php |   16 ++++++++
 skins/larry/mail.css                           |   24 +++++++++++-
 skins/larry/templates/messagepreview.html      |    2 
 7 files changed, 82 insertions(+), 13 deletions(-)

diff --git a/program/lib/Roundcube/rcube_message.php b/program/lib/Roundcube/rcube_message.php
index 4ef534a..c626af0 100644
--- a/program/lib/Roundcube/rcube_message.php
+++ b/program/lib/Roundcube/rcube_message.php
@@ -320,8 +320,15 @@
     private function parse_structure($structure, $recursive = false)
     {
         // real content-type of message/rfc822 part
-        if ($structure->mimetype == 'message/rfc822' && $structure->real_mimetype)
+        if ($structure->mimetype == 'message/rfc822' && $structure->real_mimetype) {
             $mimetype = $structure->real_mimetype;
+
+            // parse headers from message/rfc822 part
+            if (!isset($structure->headers['subject'])) {
+                list($headers, $dump) = explode("\r\n\r\n", $this->get_part_content($structure->mime_id, null, true, 4096));
+                $structure->headers = rcube_mime::parse_headers($headers);
+            }
+        }
         else
             $mimetype = $structure->mimetype;
 
diff --git a/program/lib/Roundcube/rcube_message_header.php b/program/lib/Roundcube/rcube_message_header.php
index 445d0bd..7009a00 100644
--- a/program/lib/Roundcube/rcube_message_header.php
+++ b/program/lib/Roundcube/rcube_message_header.php
@@ -235,6 +235,22 @@
             $this->others[$name] = $value;
         }
     }
+
+
+    /**
+     * Factory method to instantiate headers from a data array
+     *
+     * @param array Hash array with header values
+     * @return object rcube_message_header instance filled with headers values
+     */
+    public static function from_array($arr)
+    {
+        $obj = new rcube_message_header;
+        foreach ($arr as $k => $v)
+            $obj->set($k, $v);
+
+        return $obj;
+    }
 }
 
 
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 80dac71..8ae4101 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -5,7 +5,7 @@
  | program/steps/mail/func.inc                                           |
  |                                                                       |
  | This file is part of the Roundcube Webmail client                     |
- | Copyright (C) 2005-2010, The Roundcube Dev Team                       |
+ | Copyright (C) 2005-2012, The Roundcube Dev Team                       |
  |                                                                       |
  | Licensed under the GNU General Public License version 3 or            |
  | any later version with exceptions for skins & plugins.                |
@@ -939,13 +939,13 @@
 /**
  * return table with message headers
  */
-function rcmail_message_headers($attrib, $headers=NULL)
+function rcmail_message_headers($attrib, $headers=null)
   {
   global $OUTPUT, $MESSAGE, $PRINT_MODE, $RCMAIL;
   static $sa_attrib;
 
   // keep header table attrib
-  if (is_array($attrib) && !$sa_attrib)
+  if (is_array($attrib) && !$sa_attrib && !$attrib['valueof'])
     $sa_attrib = $attrib;
   else if (!is_array($attrib) && is_array($sa_attrib))
     $attrib = $sa_attrib;
@@ -954,8 +954,13 @@
     return FALSE;
 
   // get associative array of headers object
-  if (!$headers)
-    $headers = is_object($MESSAGE->headers) ? get_object_vars($MESSAGE->headers) : $MESSAGE->headers;
+  if (!$headers) {
+    $headers_obj = $MESSAGE->headers;
+    $headers = get_object_vars($MESSAGE->headers);
+  }
+  else {
+    $headers_obj = rcube_message_header::from_array($headers);
+  }
 
   // show these headers
   $standard_headers = array('subject', 'from', 'to', 'cc', 'bcc', 'replyto',
@@ -1031,7 +1036,7 @@
   }
 
   $plugin = $RCMAIL->plugins->exec_hook('message_headers_output',
-    array('output' => $output_headers, 'headers' => $MESSAGE->headers, 'exclude' => $exclude_headers));
+    array('output' => $output_headers, 'headers' => $headers_obj, 'exclude' => $exclude_headers));
 
   // single header value is requested
   if (!empty($attrib['valueof']))
@@ -1110,8 +1115,9 @@
 
   if (!empty($MESSAGE->parts)) {
     foreach ($MESSAGE->parts as $i => $part) {
-      if ($part->type == 'headers')
-        $out .= rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : NULL, $part->headers);
+      if ($part->type == 'headers') {
+        $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers));
+      }
       else if ($part->type == 'content') {
         // unsapported
         if ($part->realtype) {
@@ -1139,6 +1145,15 @@
         if (!isset($part->body))
           $part->body = $MESSAGE->get_part_content($part->mime_id);
 
+        // extract headers from message/rfc822 parts
+        if ($part->mimetype == 'message/rfc822') {
+          list($hdrs, $body) = explode("\r\n\r\n", $part->body, 2);
+          if ($hdrs && $body && preg_match('/^[\w-]+:\s/i', $hdrs)) {
+            $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, rcube_mime::parse_headers($hdrs)));
+            $part->body = $body;
+          }
+        }
+
         // message is cached but not exists (#1485443), or other error
         if ($part->body === false) {
           rcmail_message_error($MESSAGE->uid);
diff --git a/skins/classic/mail.css b/skins/classic/mail.css
index 85c53d5..98325d9 100644
--- a/skins/classic/mail.css
+++ b/skins/classic/mail.css
@@ -1070,6 +1070,17 @@
   background-color: #F4F4F4;
 }
 
+#messagebody table.headers-table
+{
+  margin: 16px 6px 6px 6px;
+}
+
+div.message-partheaders + div.message-part
+{
+  border-top: 0;
+  padding-top: 4px;
+}
+
 table.headers-table tr td
 {
   font-size: 11px;
diff --git a/skins/larry/mail.css b/skins/larry/mail.css
index 6512e52..12a2b7a 100644
--- a/skins/larry/mail.css
+++ b/skins/larry/mail.css
@@ -999,12 +999,14 @@
 }
 
 div.message-part,
-div.message-htmlpart {
-	padding: 0 2px 10px 2px;
+div.message-htmlpart,
+div.message-partheaders {
+	padding: 10px 2px;
 	border-top: 1px solid #ccc;
 }
 
 #messagebody div:first-child {
+	padding-top: 0;
 	border-top: 0;
 }
 
@@ -1045,6 +1047,24 @@
 	border-right: 2px solid #bb0000;
 }
 
+div.message-partheaders {
+	margin-top: 8px;
+	padding: 8px 0;
+}
+
+div.message-partheaders .headers-table {
+	width: 100%;
+}
+
+div.message-partheaders .headers-table td.header-title {
+	width: auto;
+	padding-left: 0;
+}
+
+div.message-partheaders .headers-table td.header {
+	width: 88%;
+}
+
 #messagebody > hr {
 	color: #fff;
 	background: #fff;
diff --git a/skins/larry/templates/message.html b/skins/larry/templates/message.html
index f7e188f..04381f5 100644
--- a/skins/larry/templates/message.html
+++ b/skins/larry/templates/message.html
@@ -64,7 +64,7 @@
 </div>
 <div class="leftcol">
 <roundcube:object name="messageObjects" id="message-objects" />
-<roundcube:object name="messageBody" id="messagebody" />
+<roundcube:object name="messageBody" id="messagebody" headertableclass="message-partheaders headers-table" />
 </div>
 </div>
 
diff --git a/skins/larry/templates/messagepreview.html b/skins/larry/templates/messagepreview.html
index 9eb4d1e..aef282a 100644
--- a/skins/larry/templates/messagepreview.html
+++ b/skins/larry/templates/messagepreview.html
@@ -47,7 +47,7 @@
 </div>
 <div class="leftcol">
 <roundcube:object name="messageObjects" id="message-objects" />
-<roundcube:object name="messageBody" id="messagebody" />
+<roundcube:object name="messageBody" id="messagebody" headertableclass="message-partheaders headers-table" />
 </div>
 </div>
 

--
Gitblit v1.9.1