In this tutorial you will learn on how to write a simple Private Messaging System for an existing userlogin script. I won't tell you how to write a login system, there are several good tutorials out there.
First we need to create the mysql database, I want to make it as simple as possible, so everybody can use this. That's why I only use one database, for more complex systems you should't use only one table for everything:
CREATE TABLE `messages` (
`id` INT( 11 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`title` VARCHAR( 255 ) NULL
`message` TEXT NOT NULL ,
`from` INT( 11 ) NOT NULL ,
`to` INT( 11 ) NOT NULL ,
`from_viewed` BOOL NOT NULL DEFAULT '0',
`to_viewed` BOOL NOT NULL DEFAULT '0',
`from_deleted` BOOL NOT NULL DEFAULT '0',
`to_deleted` BOOL NOT NULL DEFAULT '0',
`from_vdate` DATETIME NULL ,
`to_vdate` DATETIME NULL ,
`from_ddate` DATETIME NULL ,
`to_ddate` DATETIME NULL ,
`created` DATETIME NOT NULL
) ENGINE = MYISAM ;
However, so we got everything we need to begin with our messaging system.
The next thing is to create a small config file, where we are also creating a mysql connection.
<?php
// Your mysql-connection data
define('SQL_SERVER','localhost'); // Database Server
define('SQL_USER',''); // Your mysql User
define('SQL_PASS',''); // Your mysql Password
define('SQL_DB',''); // Your mysql database
define('MESSAGE_DELETE','1'); // How many month till a message is completly deleted
// Creating the connection using the above configuration
mysql_connect(SQL_SERVER,SQL_USER,SQL_PASS) or die("Error: ".mysql_error()); // Connection to the server
mysql_select_db(SQL_DB) or die("Error: ".mysql_error()); // Connecting to the database
?>
Those are the most common things, but now let's get to the interesting part. :) More on page 2...
So let's get it on. We will be using a small private message class that I wrote for this tutorial, it's very well commented so you can read through it, but I will explain it a little bit under the code snippet.
<?php
/***********************************************************
*
* Simple Private Messaging Tutorial Class
*
***********************************************************/
class cpm {
var $userid = '';
var $messages = array();
var $dateformat = '';
// Constructor gets initiated with userid
function cpm($user,$date="d.m.Y - H:i") {
// defining the given userid to the classuserid
$this->userid = $user;
// Define that date_format
$this->dateformat = $date;
}
// Fetch all messages from this user
function getmessages($type=0) {
// Specify what type of messages you want to fetch
switch($type) {
case "0": $sql = "SELECT * FROM messages WHERE `to` = '".$this->userid."' && `to_viewed` = '0' && `to_deleted` = '0' ORDER BY `created` DESC"; break; // New messages
case "1": $sql = "SELECT * FROM messages WHERE `to` = '".$this->userid."' && `to_viewed` = '1' && `to_deleted` = '0' ORDER BY `to_vdate` DESC"; break; // Read messages
case "2": $sql = "SELECT * FROM messages WHERE `from` = '".$this->userid."' ORDER BY `created` DESC"; break; // Send messages
case "3": $sql = "SELECT * FROM messages WHERE `to` = '".$this->userid."' && `to_deleted` = '1' ORDER BY `to_ddate` DESC"; break; // Deleted messages
default: $sql = "SELECT * FROM messages WHERE `to` = '".$this->userid."' && `to_viewed` = '0' ORDER BY `created` DESC"; break; // New messages
}
$result = mysql_query($sql) or die (mysql_error());
// Check if there are any results
if(mysql_num_rows($result)) {
$i=0;
// reset the array
$this->messages = array();
// if yes, fetch them!
while($row = mysql_fetch_assoc($result)) {
$this->messages[$i]['id'] = $row['id'];
$this->messages[$i]['title'] = $row['title'];
$this->messages[$i]['message'] = $row['message'];
$this->messages[$i]['fromid'] = $row['from'];
$this->messages[$i]['toid'] = $row['to'];
$this->messages[$i]['from'] = $this->getusername($row['from']);
$this->messages[$i]['to'] = $this->getusername($row['to']);
$this->messages[$i]['from_viewed'] = $row['from_viewed'];
$this->messages[$i]['to_viewed'] = $row['to_viewed'];
$this->messages[$i]['from_deleted'] = $row['from_deleted'];
$this->messages[$i]['to_deleted'] = $row['to_deleted'];
$this->messages[$i]['from_vdate'] = date($this->dateformat, strtotime($row['from_vdate']));
$this->messages[$i]['to_vdate'] = date($this->dateformat, strtotime($row['to_vdate']));
$this->messages[$i]['from_ddate'] = date($this->dateformat, strtotime($row['from_ddate']));
$this->messages[$i]['to_ddate'] = date($this->dateformat, strtotime($row['to_ddate']));
$this->messages[$i]['created'] = date($this->dateformat, strtotime($row['created']));
$i++;
}
} else {
// If not return false
return false;
}
}
// Fetch the username from a userid, I made this function because I don't know how you did build your usersystem, that's why I also didn't use left join... this way you can easily edit it
function getusername($userid) {
$sql = "SELECT username FROM user WHERE `id` = '".$userid."' LIMIT 1";
$result = mysql_query($sql);
// Check if there is someone with this id
if(mysql_num_rows($result)) {
// if yes get his username
$row = mysql_fetch_row($result);
return $row[0];
} else {
// if not, name him Unknown
return "Unknown";
}
}
// Fetch a specific message
function getmessage($message) {
$sql = "SELECT * FROM messages WHERE `id` = '".$message."' && (`from` = '".$this->userid."' || `to` = '".$this->userid."') LIMIT 1";
$result = mysql_query($sql);
if(mysql_num_rows($result)) {
// reset the array
$this->messages = array();
// fetch the data
$row = mysql_fetch_assoc($result);
$this->messages[0]['id'] = $row['id'];
$this->messages[0]['title'] = $row['title'];
$this->messages[0]['message'] = $row['message'];
$this->messages[0]['fromid'] = $row['from'];
$this->messages[0]['toid'] = $row['to'];
$this->messages[0]['from'] = $this->getusername($row['from']);
$this->messages[0]['to'] = $this->getusername($row['to']);
$this->messages[0]['from_viewed'] = $row['from_viewed'];
$this->messages[0]['to_viewed'] = $row['to_viewed'];
$this->messages[0]['from_deleted'] = $row['from_deleted'];
$this->messages[0]['to_deleted'] = $row['to_deleted'];
$this->messages[0]['from_vdate'] = date($this->dateformat, strtotime($row['from_vdate']));
$this->messages[0]['to_vdate'] = date($this->dateformat, strtotime($row['to_vdate']));
$this->messages[0]['from_ddate'] = date($this->dateformat, strtotime($row['from_ddate']));
$this->messages[0]['to_ddate'] = date($this->dateformat, strtotime($row['to_ddate']));
$this->messages[0]['created'] = date($this->dateformat, strtotime($row['created']));
} else {
return false;
}
}
// We need the userid for pms, but we only let users input usernames, so we need to get the userid of the username :)
function getuserid($username) {
$sql = "SELECT id FROM user WHERE `username` = '".$username."' LIMIT 1";
$result = mysql_query($sql);
if(mysql_num_rows($result)) {
$row = mysql_fetch_row($result);
return $row[0];
} else {
return false;
}
}
// Flag a message as viewed
function viewed($message) {
$sql = "UPDATE messages SET `to_viewed` = '1', `to_vdate` = NOW() WHERE `id` = '".$message."' LIMIT 1";
return (@mysql_query($sql)) ? true:false;
}
// Flag a message as deleted
function deleted($message) {
$sql = "UPDATE messages SET `to_deleted` = '1', `to_ddate` = NOW() WHERE `id` = '".$message."' LIMIT 1";
return (@mysql_query($sql)) ? true:false;
}
// Add a new personal message
function sendmessage($to,$title,$message) {
$to = $this->getuserid($to);
$sql = "INSERT INTO messages SET `to` = '".$to."', `from` = '".$this->userid."', `title` = '".$title."', `message` = '".$message."', `created` = NOW()";
return (@mysql_query($sql)) ? true:false;
}
// Render the text (in here you can easily add bbcode for example)
function render($message) {
$message = strip_tags($message, '<br>');
$message = stripslashes($message);
$message = nl2br($message);
return $message;
}
}
?>
So this is our main part of the whole tutorial, the cpm class. In here you will find everything that is neccessary to create a simple messaging system. Some parts aren't coded very nicely, but I wanted to hold it simple. It's very easy to enhance and to use.
How to use what we have now? Here is an example on how we can use this class now.
Be warned, the ouput is unlayoutet. It only shows the way on how you can implement this class. It's not hard to do a nice layout, there are also several tutorials out there. So expect nothing beautiful, it's plain unformatted text with some buttons.
Should be self-explanatory :)
<?php
/*************************************************************************
*
* Simple Private Messaging Tutorial for Pixel2Life Community
*
* Features:
*
* - Messaging using Usernames
* - No HTML allowed (bbcode can simply be included)
* - You can see if somebody has deleted or read the pm
* - On reply, the old mail will be quoted
*
* by Christian Weber
*
*
*************************************************************************/
// Load the config file!
include('config.php');
// Load the class
require('pm.php');
// Set the userid to 2 for testing purposes... you should have your own usersystem, so this should contain the userid
$userid=2;
// initiate a new pm class
$pm = new cpm($userid);
// check if a new message had been send
if(isset($_POST['newmessage'])) {
// check if there is an error while sending the message (beware, the input hasn't been checked, you should never trust users input!)
if($pm->sendmessage($_POST['to'],$_POST['subject'],$_POST['message'])) {
// Tell the user it was successful
echo "Message successfully sent!<br />";
} else {
// Tell user something went wrong it the return was false
echo "Error, couldn't send PM. Maybe wrong user.<br />";
}
}
// check if a message had been deleted
if(isset($_POST['delete'])) {
// check if there is an error during deletion of the message
if($pm->deleted($_POST['did'])) {
echo "Message successfully deleted!<br />";
} else {
echo "Error, couldn't delete PM!<br />";
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Simple private Messaging</title>
</head>
<body>
<?php
// In this switch we check what page has to be loaded, this way we just load the messages we want using numbers from 0 to 3 (0 is standart, so we don't need to type this)
if(isset($_GET['p'])) {
switch($_GET['p']) {
// get all new / unread messages
case 'new': $pm->getmessages(); break;
// get all send messages
case 'send': $pm->getmessages(2); break;
// get all read messages
case 'read': $pm->getmessages(1); break;
// get all deleted messages
case 'deleted': $pm->getmessages(3); break;
// get a specific message
case 'view': $pm->getmessage($_GET['mid']); break;
// get all new / unread messages
default: $pm->getmessages(); break;
}
} else {
// get all new / unread messages
$pm->getmessages();
}
// Standard links
?>
<a href='<?php echo $_SERVER['PHP_SELF']; ?>?p=new'>New Messages</a>
<a href='<?php echo $_SERVER['PHP_SELF']; ?>?p=send'>Send Messages</a>
<a href='<?php echo $_SERVER['PHP_SELF']; ?>?p=read'>Read Messages</a>
<a href='<?php echo $_SERVER['PHP_SELF']; ?>?p=deleted'>Deleted Messages</a>
<br /><br />
<?php
// if it's the standart startpage or the page new, then show all new messages
if(!isset($_GET['p']) || $_GET['p'] == 'new') {
?>
<table border="0" cellspacing="1" cellpadding="1">
<tr>
<td>From</td>
<td>Title</td>
<td>Date</td>
</tr>
<?php
// If there are messages, show them
if(count($pm->messages)) {
// message loop
for($i=0;$i<count($pm->messages);$i++) {
?>
<tr>
<td><?php echo $pm->messages[$i]['from']; ?></td>
<td><a href='<?php echo $_SERVER['PHP_SELF']; ?>?p=view&mid=<?php echo $pm->messages[$i]['id']; ?>'><?php echo $pm->messages[$i]['title'] ?></a></td>
<td><?php echo $pm->messages[$i]['created']; ?></td>
</tr>
<?php
}
} else {
// else... tell the user that there are no new messages
echo "<tr><td colspan='3'><strong>No new messages found</strong></td></tr>";
}
?>
</table>
<?php
// check if the user wants send messages
} elseif($_GET['p'] == 'send') {
?>
<table border="0" cellspacing="1" cellpadding="1">
<tr>
<td>To</td>
<td>Title</td>
<td>Status</td>
<td>Date</td>
</tr>
<?php
// if there are messages, show them
if(count($pm->messages)) {
// message loop
for($i=0;$i<count($pm->messages);$i++) {
?>
<tr>
<td><?php echo $pm->messages[$i]['to']; ?></td>
<td><a href='<?php echo $_SERVER['PHP_SELF']; ?>?p=view&mid=<?php echo $pm->messages[$i]['id']; ?>'><?php echo $pm->messages[$i]['title'] ?></a></td>
<td>
<?php
// If a message is deleted and not viewed
if($pm->messages[$i]['to_deleted'] && !$pm->messages[$i]['to_viewed']) {
echo "Deleted without reading";
// if a message got deleted AND viewed
} elseif($pm->messages[$i]['to_deleted'] && $pm->messages[$i]['to_viewed']) {
echo "Deleted after reading";
// if a message got not deleted but viewed
} elseif(!$pm->messages[$i]['to_deleted'] && $pm->messages[$i]['to_viewed']) {
echo "Read";
} else {
// not viewed and not deleted
echo "Not read yet";
}
?>
</td>
<td><?php echo $pm->messages[$i]['created']; ?></td>
</tr>
<?php
}
} else {
// else... tell the user that there are no new messages
echo "<tr><td colspan='4'><strong>No send messages found</strong></td></tr>";
}
?>
</table>
<?php
// check if the user wants the read messages
} elseif($_GET['p'] == 'read') {
?>
<table border="0" cellspacing="1" cellpadding="1">
<tr>
<td>From</td>
<td>Title</td>
<td>Date</td>
</tr>
<?php
// if there are messages, show them
if(count($pm->messages)) {
// message loop
for($i=0;$i<count($pm->messages);$i++) {
?>
<tr>
<td><?php echo $pm->messages[$i]['from']; ?></td>
<td><a href='<?php echo $_SERVER['PHP_SELF']; ?>?p=view&mid=<?php echo $pm->messages[$i]['id']; ?>'><?php echo $pm->messages[$i]['title'] ?></a></td>
<td><?php echo $pm->messages[$i]['to_vdate']; ?></td>
</tr>
<?php
}
} else {
// else... tell the user that there are no new messages
echo "<tr><td colspan='4'><strong>No read messages found</strong></td></tr>";
}
?>
</table>
<?php
// check if the user wants the deleted messages
} elseif($_GET['p'] == 'deleted') {
?>
<table border="0" cellspacing="1" cellpadding="1">
<tr>
<td>From</td>
<td>Title</td>
<td>Date</td>
</tr>
<?php
// if there are messages, show them
if(count($pm->messages)) {
// message loop
for($i=0;$i<count($pm->messages);$i++) {
?>
<tr>
<td><?php echo $pm->messages[$i]['from']; ?></td>
<td><a href='<?php echo $_SERVER['PHP_SELF']; ?>?p=view&mid=<?php echo $pm->messages[$i]['id']; ?>'><?php echo $pm->messages[$i]['title'] ?></a></td>
<td><?php echo $pm->messages[$i]['to_ddate']; ?></td>
</tr>
<?php
}
} else {
// else... tell the user that there are no new messages
echo "<tr><td colspan='4'><strong>No deleted messages found</strong></td></tr>";
}
?>
</table>
<?php
// if the user wants a detail view and the message id is set...
} elseif($_GET['p'] == 'view' && isset($_GET['mid'])) {
// if the users id is the recipients id and the message hadn't been viewed yet
if($userid == $pm->messages[0]['toid'] && !$pm->messages[0]['to_viewed']) {
// set the messages flag to viewed
$pm->viewed($pm->messages[0]['id']);
}
?>
<table border="0" cellspacing="1" cellpadding="1">
<tr>
<td>From:</td>
<td><?php echo $pm->messages[0]['from']; ?></td>
<td colspan="2"></td>
</tr>
<tr>
<td>Date:</td>
<td><?php echo $pm->messages[0]['created']; ?></td>
<td colspan="2"></td>
</tr>
<tr>
<td>Subject:</td>
<td colspan="3"><?php echo $pm->messages[0]['title']; ?></td>
</tr>
<tr>
<td colspan="4"><?php echo $pm->render($pm->messages[0]['message']); ?></td>
</tr>
</table>
<form name='reply' method='post' action='<?php echo $_SERVER['PHP_SELF']; ?>'>
<input type='hidden' name='rfrom' value='<?php echo $pm->messages[0]['from']; ?>' />
<input type='hidden' name='rsubject' value='Re: <?php echo $pm->messages[0]['title']; ?>' />
<input type='hidden' name='rmessage' value='[quote]<?php echo $pm->messages[0]['message']; ?>[/quote]' />
<input type='submit' name='reply' value='Reply' />
</form>
<form name='delete' method='post' action='<?php echo $_SERVER['PHP_SELF']; ?>'>
<input type='hidden' name='did' value='<?php echo $pm->messages[0]['id']; ?>' />
<input type='submit' name='delete' value='Delete' />
</form>
<?php
}
?>
<form name="new" method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
<strong>To:</strong><br />
<input type='text' name='to' value='<?php if(isset($_POST['reply'])) { echo $_POST['rfrom']; } ?>' /><br />
<strong>Subject:</strong><br />
<input type='text' name='subject' value='<?php if(isset($_POST['reply'])) { echo $_POST['rsubject']; } ?>' /><br />
<strong>Message:</strong><br />
<textarea name='message'><?php if(isset($_POST['reply'])) { echo $_POST['rmessage']; } ?></textarea><br />
<input type='submit' name='newmessage' value='Send' />
</form>
</body>
</html>
Well I hope you liked it and that it worked for you, if you have any questions regarding advanced features or having problems with this, feel free to pm me or to comment this. I'll try to reply as soon as possible.
Regards,
Christian Weber