Public and Private Messages [ 212 ] /** * The registry object */ private $registry; /** * ID of the message */ private $id=0; /** * ID of the sender */ private $sender; /** * Name of the sender */ private $senderName; /** * ID of the recipient */ private $recipient; /** * Name of the recipient */ private $recipientName; /** * Subject of the message */ private $subject; /** * When the message was sent (TIMESTAMP) */ private $sent; /** * User readable, friendly format of the time the message was sent */ This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Chapter 7 [ 213 ] private $sentFriendlyTime; /** * Has the message been read */ private $read=0; /** * The message content itself */ private $message; The constructor takes the registry and ID of the message as parameters, if the ID has been dened, then it queries the database and sets the class variables. The database query here also formats a copy of the date into a friendlier format, and looks up the names of the sender and recipient of the message: /** * Message constructor * @param Registry $registry the registry object * @param int $id the ID of the message * @return void */ public function __construct( Registry $registry, $id=0 ) { $this->registry = $registry; $this->id = $id; if( $this->id > 0 ) { $sql = "SELECT m.*, DATE_FORMAT(m.sent, '%D %M %Y') as sent_friendly, psender.name as sender_name, precipient.name as recipient_name FROM messages m, profile psender, profile precipient WHERE precipient.user_id=m.recipient AND psender.user_id=m.sender AND m.ID=" . $this->id; $this->registry->getObject('db')->executeQuery( $sql ); if( $this->registry->getObject('db')->numRows() > 0 ) { $data = $this->registry->getObject('db')->getRows(); $this->sender = $data['sender']; $this->recipient = $data['recipient']; $this->sent = $data['sent']; $this->read = $data['read']; $this->subject = $data['subject']; $this->message = $data['message']; This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Public and Private Messages [ 214 ] $this->sentFriendlyTime = $data['sent_friendly']; $this->senderName = $data['sender_name']; $this->recipientName = $data['recipient_name']; } else { $this->id = 0; } } } Next, we have setter methods for most of the class variables: /** * Set the sender of the message * @param int $sender * @return void */ public function setSender( $sender ) { $this->sender = $sender; } /** * Set the recipient of the message * @param int $recipient * @return void */ public function setRecipient( $recipient ) { $this->recipient = $recipient; } /** * Set the subject of the message * @param String $subject * @return void */ public function setSubject( $subject ) { $this->subject = $subject; } /** This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Chapter 7 [ 215 ] * Set if the message has been read * @param boolean $read * @return void */ public function setRead( $read ) { $this->read = $read; } /** * Set the message itself * @param String $message * @return void */ public function setMessage( $message ) { $this->message = $message; } The save method takes the class variables that directly relate to the messages table in the database and either inserts them as a new record, or updates the existing record: /** * Save the message into the database * @return void */ public function save() { if( $this->id > 0 ) { $update = array(); $update['sender'] = $this->sender; $update['recipient'] = $this->recipient; $update['read'] = $this->read; $update['subject'] = $this->subject; $update['message'] = $this->message; $this->registry->getObject('db')->updateRecords( 'messages', $update, 'ID=' . $this->id ); } else { $insert = array(); $insert['sender'] = $this->sender; $insert['recipient'] = $this->recipient; $insert['read'] = $this->read; This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Public and Private Messages [ 216 ] $insert['subject'] = $this->subject; $insert['message'] = $this->message; $this->registry->getObject('db')->insertRecords( 'messages', $insert ); $this->id = $this->registry->getObject('db')->lastInsertID(); } } One getter method that we need, is to return the user ID of the recipient, so we can check that the currently logged in user has permission to read the message: /** * Get the recipient of the message * @return int */ public function getRecipient() { return $this->recipient; } We should also provide a method to delete the message from the database, should the user wish to delete a message: /** * Delete the current message * @return boolean */ public function delete() { $sql = "DELETE FROM messages WHERE ID=" . $this->id; $this->registry->getObject('db')->executeQuery( $sql ); if( $this->registry->getObject('db')->affectedRows() > 0 ) { $this->id =0; return true; } else { return false; } } This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Chapter 7 [ 217 ] Finally, we have a toTags method, which converts all of the non-object and non-array variables into template tags, so when we create a view message method in the controller, we simply need to construct the message object and call the toTags method: /** * Convert the message data to template tags * @param String $prefix prefix for the template tags * @return void */ public function toTags( $prefix='' ) { foreach( $this as $field => $data ) { if( ! is_object( $data ) && ! is_array( $data ) ) { $this->registry->getObject('template')->getPage()->addTag( $prefix.$field, $data ); } } } } ?> Messages model Similar to how we have a model for representing a single relationship and another for representing a number of relationships, we also need a model to represent a number of messages within the site. This is to handle the lookup of a user's private message inbox. <?php /** * Messages model */ class Messages { /** * Messages constructor * @param Registry $registry * @return void This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Public and Private Messages [ 218 ] */ public function __construct( Registry $registry ) { $this->registry = $registry; } /** * Get a users inbox * @param int $user the user * @return int the cache of messages */ public function getInbox( $user ) { $sql = "SELECT IF(m.read=0,'unread','read') as read_style, m.subject, m.ID, m.sender, m.recipient, DATE_FORMAT(m.sent, '%D %M %Y') as sent_friendly, psender.name as sender_name FROM messages m, profile psender WHERE psender.user_id=m.sender AND m.recipient=" . $user . " ORDER BY m.ID DESC"; $cache = $this->registry->getObject('db')->cacheQuery( $sql ); return $cache; } } ?> Controllers and views Our controller needs functionality for: • Listing a user's private messages ° Indicating which messages have been read, and which ones are unread • Reading a message • Deleting a message • Composing a new message And we need three templates, for: • Our inbox • Viewing a message • Creating a new message This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Chapter 7 [ 219 ] Listing messages To list our messages, we simply require our messages controller, call the getInbox method, and send the cache to the template engine. The read_style eld in the results of the query can be used to highlight rows in the messages table (HTML table in the view), which represent unread messages: /** * View your inbox * @return void */ private function viewInbox() { require_once( FRAMEWORK_PATH . 'models/messages.php' ); $messages = new Messages( $this->registry ); $cache = $messages->getInbox( $this->registry- >getObject('authenticate')->getUser()->getUserID() ); $this->registry->getObject('template')- >buildFromTemplates('header.tpl.php', 'messages/inbox.tpl.php', 'footer.tpl.php'); $this->registry->getObject('template')->getPage()- >addTag( 'messages', array( 'SQL', $cache ) ); } Inbox The inbox template (views/default/templates/messages/inbox.tpl.php)) simply requires a table with a template loop to contain the messages. Notice that the class of the table row is set based on whether the message has been read or not: <div id="main"> <div id="rightside"> <ul> <li><a href="messages/create">Create a new message</a></a> </ul> </div> <div id="content"> <h1>Your inbox</h1> <table> <tr> <th>From</th> <th>Subject</th> This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Public and Private Messages [ 220 ] <th>Sent</th> </tr> <! START messages > <tr class="{read_style}"> <td>{sender_name}</td> <td><a href="messages/view/{ID}">{subject}</a></td> <td>{sent_friendly}</td> </tr> <! END messages > </table> </div> </div> The following screenshot shows the Inbox feature: Reading a message To read a message we need to require our message model, construct the message object with the registry and message ID, check that the recipient is the currently logged in user, load the template, and send the message information to the template: /** * View a message * @param int $message the ID of the message * @return void */ private function viewMessage( $message ) { require_once( FRAMEWORK_PATH . 'models/message.php' ); $message = new Message( $this->registry, $message ); This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com Chapter 7 [ 221 ] if( $message->getRecipient() == $this->registry- >getObject('authenticate')->getUser()->getUserID() ) { $this->registry->getObject('template')- >buildFromTemplates('header.tpl.php', 'messages/view.tpl.php', 'footer.tpl.php'); $message->toTags( 'inbox_' ); } else { $this->registry->errorPage( 'Access denied', 'Sorry, you are not allowed to view that message'); } } View message template The view message template (views/default/templates/messages/view.tpl. php) simply contains template tags for the message properties, and a few additional links: <div id="main"> <div id="rightside"> <ul> <li><a href="messages/">Your inbox</a></a> <li><a href="messages/create/{inbox_id}"> Reply to this message</a></a> <li><a href="messages/delete/{inbox_id}"> Delete this message</a></a> <li><a href="messages/create">Create a new message</a></a> </ul> </div> <div id="content"> <h1>View message</h1> <table> <tr> <th>Subject</th> <td>{inbox_subject}</td> </tr> <tr> <th>From</th> <td>{inbox_senderName}</td> </tr> This material is copyright and is licensed for the sole use by RAYMOND ERAZO on 25th October 2010 3146 KERNAN LAKE CIRCLE, JACKSONVILLE, 32246 Download from www.eBookTM.com . . $this->id; $this->registry->getObject('db' )-& gt;executeQuery( $sql ); if( $this->registry->getObject('db' )-& gt;numRows() > 0 ) { $data = $this->registry->getObject('db' )-& gt;getRows(); . . $this->id; $this->registry->getObject('db' )-& gt;executeQuery( $sql ); if( $this->registry->getObject('db' )-& gt;affectedRows() > 0 ) { $this->id. $this->registry->getObject('template' )- >buildFromTemplates('header.tpl .php& apos;, 'messages/inbox.tpl .php& apos;, 'footer.tpl .php& apos;); $this->registry->getObject('template' )-& gt;getPage()-