Nmsgs; // initialize messages array $messages = array(); // create the message array for($i=0;$i<=$message_count-1;$i++){ $letter = imap_headerinfo($mailbox, $i + 1); $message_id = $letter->message_id; $messages[$message_id] = array(); $messages[$message_id]['id'] = $message_id; $messages[$message_id]['from_email'] = $letter->sender[0]->mailbox ."@".$letter->sender[0]->host; $messages[$message_id]['from'] = $letter->sender[0]->personal; // if there is no sender name, replace it with name of email if (strlen($messages[$message_id]['from']) == 0){ $messages[$message_id]['from'] = substr($messages[$message_id]['from_email'],0,strpos($messages[$message_id]['from_email'],'@')); } $messages[$message_id]['date'] = $letter->date; $messages[$message_id]['subject'] = $letter->subject; // parent message id (this is usually the most appropriate) $messages[$message_id]['parent_id'] = array(); if (strlen($letter->in_reply_to) != 0) { $messages[$message_id]['parent_id'] = array($letter->in_reply_to=>$letter->in_reply_to); } // message references. typically a history of message-ids $messages[$message_id]['references'] = array(); if (strlen($letter->references) != 0) { foreach(split(' ',$letter->references) AS $reference) $messages[$message_id]['references'][$reference] = $reference; } // typically last parent element is the _real_ parent $messages[$message_id]['parents'] = array_merge($messages[$message_id]['references'],$messages[$message_id]['parent_id']); // flags a not threaded message (use string for easier debug/display) $messages[$message_id]['thread'] = 'not threaded'; } // view the message array //dump_array($messages,true);exit; loop_messages($messages); // view the threading array //dump_array($threading,true);exit; loop_array($threading); // loops through threaded array to display threading function loop_array($target){ print ''; } // loop messages // once this loop is finished // the threading array will contain the thread list // looping through it will allow the processing of // the full message from message array function loop_messages(&$messages){ // initailize the arrays; global $subject_thread; global $threading; $subject_thread = array(); $threading = array(); foreach($messages AS $message){ // assume every message is a child $child_id = $message['id']; // find the newest existing message as the parent $parent_id = ''; foreach($message['parents'] AS $parent){ if (array_key_exists($parent,$messages) AND $parent != $child_id) $parent_id = $parent; } // print 'Child: ' . htmlentities($child_id) . '
'; add_node($parent_id,$child_id,$messages); // print '==================
'; } } // recursively checks parent_id to determine if // it exists in messages array, and adds each thread level // as needed. Once thread for child is created, adds the // child node to existing thread. function add_node($parent_id,$child_id,&$messages){ global $threading; global $subject_thread; // already has been added if (is_array($messages[$child_id]['thread'])) return; $subject = trim($messages[$child_id]['subject']); $from = $messages[$child_id]['from']; // check if parent is present if (array_key_exists($parent_id,$messages)){ // check if parent has been threaded if (!is_array($message[$parent_id]['thread'])){ // print 'add: ' . $parent_id . '

'; // parent becomes child // find newest existing message as parent foreach($messages[$parent_id]['parents'] AS $parent){ if (array_key_exists($parent,$messages) AND $parent != $parent_id) $grand_parent_id = $parent; } // print htmlentities($grand_parent_id) . '
'; add_node($grand_parent_id,$parent_id,$messages); } // update the message thread index $messages[$child_id]['thread'] = $messages[$parent_id]['thread']; $messages[$child_id]['thread'][] = $child_id; // create the dynamic multi-dimensions for the threading array foreach ($messages[$child_id]['thread'] AS $thread){ $level .= "['{$thread}']['children']"; } $level = substr($level,0,strlen($level) - 12); // print $level . '
------------------
'; // take thread array and add message to it eval("\$threading{$level}['info'] = \$subject . '---' . \$from;"); eval("\$threading{$level}['thread'] = \$messages[\$child_id]['thread'];"); }else{ // parent doesnt exist // check to see if if subject threading could happen // this does not take into account non-chronological messages. // therefore assumes first subject message will be parent // replace re: $subject_md5 = md5(trim(str_ireplace('re:', '', $subject))); // you can be less restrictive by not requiing the RE: at the start of the subject // for subject matching. if (array_key_exists($subject_md5,$subject_thread) AND strtoupper(substr($subject,0,3)) == 'RE:'){ $parent_id = $subject_thread[$subject_md5]['id']; add_node($parent_id,$child_id,$messages); }else { // message (child) is first for thread $subject_thread[$subject_md5]['id'] = $child_id; $threading[$child_id]['info'] = $subject . '---' . $from; $messages[$child_id]['thread'] = array($child_id); // print 'Top: ' . $child['id'] . '
------------------
'; } } } // display utility for arrays function dump_array($array,$print=false){ // returns a formatted array dump $output = highlight_string(print_r($array,true),true); if ($print) print $output; return $output; } ?>