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 '
';
foreach($target AS $child){
print "- {$child['info']}
";
if (array_key_exists('children',$child)) loop_array($child['children']);
}
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;
}
?>