7 min read

We obviously need to keep private messages separate from the rest of the site, and ensure that they are only accessible to the sender and the receiver. While we could alter the public messages feature developed earlier, this would raise a few issues, such as being more difficult to tell whether the message being sent or read was private, and when using the Internet in a public area, the message would be shown on the area of the social network the user would most likely be visiting, which isn’t ideal for private information.

Because private messages will be separate from statuses, and won’t need to make use of other media types to make them more interesting (though, we could set them up to make use of other media if we wanted), it makes sense for us to also use separate database tables and models for this feature.

Database

Our database needs provisions for the sender of the message, the recipient of the message, the subject of the message, and of course the message itself. We should also provide for if the message has been read, when the message was sent, and an ID for the message.

The following illustrates a suitable structure for a messages table in our database:

 

Field

Type

Description

ID

Integer, Autoincrement, Primary Key

Reference ID for the message

Sender

Integer

The sender of the message

Recipient

Integer

The recipient of the message

Subject

Varchar

The subject the message relates to

Sent

Timestamp

When the message was sent

Message

Longtext

The contents of the message itself

Read

Boolean

Indicates whether the message has been read or not

More than one recipient?
This database structure, and the code that follows, only supports one recipient per message. Our users might want to send to more than one recipient—feel free to add this functionality if you wish.

Message model

As with the majority of our database access, we require a model (models/message. php) to create, update, and retrieve message-related data from the database and encapsulate it within itself.

It would also be helpful if the model pulled in a little more information from the database, including:

  • A more user friendly representation of the date (we can get this via the MySQL DATE_FORMAT function)
  • The name of the sender, by joining the messages table to the profile table
  • The name of the recipient, by joining the messages table to the profile table again

The first part of our model simply defines the class variables:

/**
* Private message class
*/
class Message {

/**
* 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
*/
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 defined, 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->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;
}

/**
* 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;
$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;
}
}


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.

/**
* Messages model
*/
class Messages {

/**
* Messages constructor
* @param Registry $registry
* @return void
*/
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;

}
}
?>



Subscribe to the weekly Packt Hub newsletter. We'll send you this year's Skill Up Developer Skills Report.

* indicates required

LEAVE A REPLY

Please enter your comment!
Please enter your name here