Coding PHP Mailboxes (Part 1)

Page 3 - Viewing Mail

Skip to navigation

Having the list of emails is all well and good, but it's not really that much use unless you can also view the contents of the email is it? So the next task is to get it to view the emails when you click on one of the email headers. To start with, lets create a new function that when given a mailbox resource and a message number, it will return the contents of the email.

function getMessage ($mb, $id)
{
   $msg = array();
   $msg['head'] = imap_fetch_overview($mb, $id);
   $msg['body'] = array();
   $i = 0;
   while(imap_fetchbody ($mb, $id, $i)) {
      $msg['body'][] = str_replace("\t", " ", 
         nl2br(htmlentities(imap_fetchbody ($mb, $id, $i++))));
   }
   return $msg;
}

What this function does is retrieve an overview of the email and also every part of the body, and stores them all in seperate parts of an array and returns it. This might also end up being used for Ajax which is why it does none of the HTML printing here. Now we can move on to the function that prints the email.

function showMessage($mb, $id)
{
   $message = getMessage($mb, $id);
   echo '
   <h2>'.$message['head'][0]->subject.'</h2>
   <h3><strong>'.strip_tags($message['head'][0]->from).'</strong> to '
                      .strip_tags($message['head'][0]->to).'
      <em>'.$message['head'][0]->date.'</em></h3>
   <div id="mail_headerInfo">
      <p>'.$message['body'][0].'</p>
   </div>
   <div id="mail_body">
      <p>'.$message['body'][1].'</p>
   </div>';
}

The assumption is made that the page already contains a h1, and so uses h2 to keep the markup semantically correct. h1 is the header of the page, and then h2 is the header of the content - makes sense. The header information is all kept inside a div with an ID so we can easily collapse the div using Javascript.

As it currently stands we have functions for listing the messages, and showing the messages, and another for connecting to the mailbox. At the minute there is no way of clicking on an email message and viewing the email message even though the functions for displaying them are there. To display the emails we're going to use a bit of Ajax - this saves have to refresh the page for every email that you want to show, and helps reduce the server load a little by not having to reload the rest of the page. To start with you will need to download Scriptaculous and put it in a subfolder called "js". Now in the header of the page for showing emails add the following lines:

<script type="text/javascript" src="./js/prototype.js"></script>
<script type="text/javascript" src="./js/scriptaculous.js"></script>
<script type="text/javascript" src="./js/email.js"></script>

This will include the functions we need for making an XML request to a PHP page. The first two javascript files are the one's from prototype and scriptaculous, they are the ones doing all the cool Ajax type stuff, and the last file will be the one where we keep our own functions. Inside email.js you will want to add the following:

function showEmailMessage(id)
{
   new Ajax.Updater('mail_message', 'neobox.php', {
      method: 'post',
      parameters: 'getMessage=' + id,
   });
}


function attachFunctions ()
{
   var mails = document.getElementById('mail_list').getElementsByTagName('li');
   for (var i in mails) {
      if(mails[i] && mails[i].id != undefined) {
         mails[i].onclick = function ()
         {
            showEmailMessage(this.id.replace(/messageID/gi, ''));
         }
      }
   }
}

window.onload = function () { attachFunctions(); }

The first function uses an Ajax call to the page we made previously (in my case I named it neobox.php) and say that whatever we get back from it is going to be the innerHTML for the element with the id of "mail_message". This request is made using POST variable with getMessage being equal to the id of whichever message we want to view. The function, attachFunctions is then used on when the page has done loading to attach the showEmailMessage function to the onclick event for every list item in the mail_list.