612 Chapter 27 Building a Web-Based Email Service case 'show-headers' : case 'hide-headers' : case 'view-message' : { // if we have just picked a message from the list, or were looking at // a message and chose to hide or view headers, load a message $fullheaders = ($action=='show-headers'); display_message($HTTP_SESSION_VARS['auth_user'], $HTTP_SESSION_VARS['selected_account'], $messageid, $fullheaders); break; } You’ll notice that we’re checking the value of the $action being equal to 'show-headers'. In this case, it will be false,and $fullheaders will be set equal to false.We’ll look at the 'show-headers' action in a moment. The line $fullheaders = ($action=='show-headers'); could have been more verbosely—but perhaps more clearly—written as if($action=='show-headers') $fullheaders = true; else $fullheaders = false; Next, we call the display_message() function. Most of this function outputs plain HTML, so we will not go through it here. It calls the retrieve_message() function to get the appropriate message from the mailbox: $message = retrieve_message($auth_user, $accountid, $messageid, $fullheaders); The retrieve_message() function is in the mail_fns.php library.You can see the code for it in Listing 27.10. Listing 27.10 retrieve_message() Function from mail_fns.php—This Function Retrieves One Specific Message from a Mailbox function retrieve_message($auth_user, $accountid, $messageid, $fullheaders) { $message = array(); if(!($auth_user && $messageid && $accountid)) return false; $imap = open_mailbox($auth_user, $accountid); if(!$imap) return false; 33 525x ch27 1/24/03 2:56 PM Page 612 613 Reading Mail $header = imap_header($imap, $messageid); if(!$header) return false; $message['body'] = imap_body($imap, $messageid); if(!$message['body']) $message['body'] = "[This message has no body]\n\n\n\n\n\n"; if($fullheaders) $message['fullheaders'] = imap_fetchheader($imap, $messageid); else $message['fullheaders'] = ''; $message['subject'] = $header->subject; $message['fromaddress'] = $header->fromaddress; $message['toaddress'] = $header->toaddress; $message['ccaddress'] = $header->ccaddress; $message['date'] = $header->date; // note we can get more detailed information by using from and to // rather than fromaddress and toaddress, but these are easier imap_close($imap); return $message; } Again we have used open_mailbox() to open the user’s mailbox. This time, however, we are after a specific message. Using this function library, we download the message headers and message body separately. The three IMAP functions we use here are imap_header(), imap_ fetchheader() ,and imap_body().Note that the two header functions are distinct from imap_headers(), the one we used previously.They are somewhat confusingly named. In summary, n imap_headers()—Returns a summary of the headers for all the messages in a mailbox. It returns them as an array with one element per message. n imap_header()—Returns the headers for one specific message in the form of an object. n imap_fetchheader()—Returns the headers for one specific message in the form of a string. In this case we use imap_header() to fill out specific header fields and imap_ fetchheader() to show the user the full headers if requested. (We’ll come back to this.) Listing 27.10 Continued 33 525x ch27 1/24/03 2:56 PM Page 613 614 Chapter 27 Building a Web-Based Email Service We use imap_header() and imap_body() to build an array containing all the elements of a message that we are interested in. We call imap_header() as follows: $header = imap_header($imap, $messageid); We can then extract each of the fields we require from the object: $message['subject'] = $header->subject; We call imap_body() to add the message body to our array as follows: $message['body'] = imap_body($imap, $messageid); Finally we close the mailbox with imap_close() and return the array we have built.The display_message() function can then display the message’s fields in the form you can see in Figure 27.6. Viewing Message Headers As you can see in Figure 27.6, there is a Show Headers button.This activates the show- headers option, which adds the full message headers to the message display. If the user clicks this button, he will see output similar to that shown in Figure 27.7. Figure 27.7 Using show-headers to see the full headers for this message will help a user track down the source of the spam. 33 525x ch27 1/24/03 2:56 PM Page 614 615 Reading Mail As you probably noticed, the event handling for view-message covers show-headers (and its counterpart hide-headers) too. If this option is selected, we do the same things as before. But in retrieve_message(),we also grab the full text of the headers, as follows: if($fullheaders) $message['fullheaders'] = imap_fetchheader($imap, $messageid); We can then display these headers for the user. Deleting Mail If a user clicks the Delete button on a particular email, he will activate the "delete" action.This will execute the following code from index.php: case 'delete' : { delete_message($HTTP_SESSION_VARS['auth_user'], $HTTP_SESSION_VARS['selected_account'], $messageid); //note deliberately no 'break' - we will continue to the next case } case 'select-account' : case 'view-mailbox' : { // if mailbox just chosen, or view mailbox chosen, show mailbox display_list($HTTP_SESSION_VARS['auth_user'], $HTTP_SESSION_VARS['selected_account']); break; } As you can see, the message is deleted using the delete_message() function, and then the resulting mailbox is displayed as discussed previously. The code for the delete_message() function is shown in Listing 27.11. Listing 27.11 delete_message() Function from mail_fns.php—This Function Deletes One Specific Message from a Mailbox function delete_message($auth_user, $accountid, $message_id) { // delete a single message from the server $imap = open_mailbox($auth_user, $accountid); if($imap) { imap_delete($imap, $message_id); imap_expunge($imap); imap_close($imap); return true; 33 525x ch27 1/24/03 2:56 PM Page 615 616 Chapter 27 Building a Web-Based Email Service } return false; } As you can see, this function uses a number of the IMAP functions.The new ones are imap_delete() and imap_expunge().Note that imap_delete() only marks messages for deletion.You can mark as many messages as you like.The call to imap_expunge() actually deletes the messages. Sending Mail Finally we come to sending mail.There are a few ways to do this from this script:The user can send a new message, reply to, or forward mail. Let’s see how these work. Sending a New Message The user can choose this option by clicking the New Message button.This activates the "new-message" action, which executes the following code in index.php: case 'new-message' : { display_new_message_form($HTTP_SESSION_VARS['auth_user'], $to, $cc, $subject, $body); break; } The new message form is just a form for sending mail.You can see what it looks like in Figure 27.8.This figure actually shows mail forwarding rather than new mail, but the form is the same.We’ll look at forwarding and replies next. Clicking the Send Message button invokes the "send-message" action, which exe- cutes the following code: case 'send-message' : { if(send_message($to, $cc, $subject, $message)) echo "<p>Message sent.</p><br /><br /><br /><br /><br /><br />"; else echo "<p>Could not send message.</p><br /><br /><br /><br /><br /><br />"; break; } This code calls the send_message() function, which actually sends the mail.This func- tion is shown in Listing 27.12. Listing 27.11 Continued 33 525x ch27 1/24/03 2:56 PM Page 616 . 612 Chapter 27 Building a Web- Based Email Service case 'show-headers' : case 'hide-headers' : case 'view-message' : { // if we have just picked. Page 614 615 Reading Mail As you probably noticed, the event handling for view-message covers show-headers (and its counterpart hide-headers) too. If this option is selected, we do the same things as. = $header->subject; $message['fromaddress'] = $header->fromaddress; $message['toaddress'] = $header->toaddress; $message['ccaddress'] = $header->ccaddress; $message['date']