The code for the plugin is
<?php
/***********************************************************************
Copyright (C) 2002-2005 Neal Poole (smartys@gmail.com)
This file is part of PunBB.
PunBB is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published
by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
PunBB is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307 USA
************************************************************************/
// Make sure no one attempts to run this script "directly"
if (!defined('PUN'))
exit;
// Tell admin_loader.php that this is indeed a plugin and that it is loaded
define('PUN_PLUGIN_LOADED', 1);
// We're adding an index
if (isset($_POST['index']))
{
// Turn off PHP time limit
@set_time_limit(0);
// Lets go through the list of indexes and see if we already did this
$result = $db->query('SHOW INDEX FROM '.$db->prefix.'messages') or error('Unable to check for index', __FILE__, __LINE__, $db->error());
while ($cur_index = $db->fetch_assoc($result))
{
if ($cur_index['Key_name'] == 'pm_message_idx')
message('It looks like you have already created the correct index');
}
// Add the index
$db->query('ALTER TABLE '.$db->prefix.'messages ADD FULLTEXT INDEX pm_message_idx (message)') or error('Unable to add index', __FILE__, __LINE__, $db->error());
message('The index was successfully added.');
}
// If we're deleting messages
else if (isset($_POST['delete']))
{
confirm_referrer('admin_loader.php');
if (!isset($_POST['del_message']) || empty($_POST['del_message']))
message('You must select at least one message to delete!');
$messages = array_values(array_map("intval", $_POST['del_message']));
$messages = implode(',', $messages);
$db->query('DELETE FROM '.$db->prefix.'messages WHERE id IN ('.$messages.')') or error('Unable to delete messages', __FILE__, __LINE__, $db->error());
message('Messages deleted');
}
// If we're trying to view a message
else if (isset($_GET['view_id']))
{
require PUN_ROOT.'include/parser.php';
$id = intval($_GET['view_id']);
$result = $db->query('SELECT m.*, u.username AS owner_name FROM '.$db->prefix.'messages AS m INNER JOIN '.$db->prefix.'users AS u ON (u.id = m.owner) WHERE m.id = '.$id) or error('Unable to fetch message', __FILE__, __LINE__, $db->error());
if ($db->num_rows($result) < 1)
message($lang_common['Bad request']);
// Display the admin navigation menu
generate_admin_menu($plugin);
$message = $db->fetch_assoc($result);
$message['smileys'] = isset($message['smileys']) ? $message['smileys'] : $pun_user['show_smilies'];
$message['message'] = parse_message($message['message'], (int)(!$message['smileys']));
?>
<div id="p<?php echo $message['id'] ?>" class="blockpost row_odd firstpost blockform">
<h2><span>View Message</span></h2>
<div class="box">
<div class="inbox">
<div class="postleft">
<dl>
<dt><small>On <?php echo format_time($message['posted']) ?>, <strong><a href="profile.php?id=<?php echo $message['sender_id'] ?>"><?php echo pun_htmlspecialchars($message['sender']) ?></a></strong> sent the following message to <strong><a href="profile.php?id=<?php echo $message['owner'] ?>"><?php echo pun_htmlspecialchars($message['owner_name']) ?></a></strong></small></dt>
</dl>
</div>
<div class="postright">
<div class="postmsg">
<?php echo $message['message']."\n" ?>
</div>
</div>
</div>
</div>
</div>
<?php
}
// If the "Search" button was clicked
else if (isset($_POST['search']))
{
$sender = intval($_POST['sender']);
$recipient = intval($_POST['recipient']);
if ($sender < 1 || $recipient < 1)
message($lang_common['Bad request']);
$keywords = trim($db->escape($_POST['keywords']));
// Form the correct where statement
$where_sql = array();
if (strlen($keywords) > 0)
$where_sql[] = 'match(message) against ("'.$keywords.'" IN BOOLEAN MODE)';
if ($sender > 1)
$where_sql[] = 'sender_id = '.$sender;
if ($recipient > 1)
$where_sql[] = 'owner = '.$recipient;
if (empty($where_sql))
message('You must enter at least one keyword and/or a sender and/or a recipient if you wish to search');
// Format the SQL properly
$where_sql = implode(' and ', $where_sql);
$result = $db->query('SELECT m.*, u.username AS owner_name FROM '.$db->prefix.'messages AS m INNER JOIN '.$db->prefix.'users AS u ON (u.id = m.owner) WHERE '.$where_sql.' ORDER BY posted DESC') or error('Unable to fetch messages list', __FILE__, __LINE__, $db->error());
if ($db->num_rows($result) < 1)
message('No messages matched your search criteria');
?>
<div class="blocktable">
<h2><span>Search Results</span></h2>
<form id="search_results" method="post" action="<?php echo $_SERVER['REQUEST_URI'] ?>">
<div class="box">
<div class="inbox">
<table cellspacing="0">
<tr>
<th width="20"></th>
<th>Subject</th>
<th>Sender</th>
<th>Reciever</th>
<th>Date Sent</th>
</tr>
<?php
while ($cur_message = $db->fetch_assoc($result))
{
?>
<tr>
<td><input type="checkbox" name="del_message[]" value="<?php echo $cur_message['id'] ?>" /></td>
<td><a href="<?php echo $_SERVER['REQUEST_URI'] ?>&view_id=<?php echo $cur_message['id'] ?>"><?php echo pun_htmlspecialchars($cur_message['subject']) ?></a></td>
<td><a href="profile.php?id=<?php echo $cur_message['sender_id'] ?>"><?php echo pun_htmlspecialchars($cur_message['sender']) ?></a></td>
<td><a href="profile.php?id=<?php echo $cur_message['owner'] ?>"><?php echo pun_htmlspecialchars($cur_message['owner_name']) ?></a></td>
<td><?php echo format_time($cur_message['posted']) ?></td>
</tr>
<?php
}
?>
</table>
</div>
</div>
<p><input type="submit" name="delete" value="Delete multiple messages" /></p>
</form>
<?php
}
else // If not, we show the form
{
$result = $db->query('SELECT id, username FROM '.$db->prefix.'users WHERE id > 1 ORDER BY id ASC') or error('Unable to grab user list', __FILE__, __LINE__, $db->error());
$users = array();
while ($cur_user = $db->fetch_assoc($result))
{
$users[] = $cur_user;
}
// Display the admin navigation menu
generate_admin_menu($plugin);
?>
<div id="exampleplugin" class="blockform">
<h2><span>Monitor Private Messages</span></h2>
<div class="box">
<div class="inbox">
<p>This plugin allows you to easily and simply monitor the private messages sent by your users</p>
<form id="search" method="post" action="<?php echo $_SERVER['REQUEST_URI'] ?>&foo=bar">
<div class="inform">
<fieldset>
<legend>New search</legend>
<div class="infldset">
<label class="conl">Keyword search<br /><input type="text" name="keywords" size="40" maxlength="100" /><br /></label>
<label class="conl">Sender search<br /><select name="sender"><option value="1">All users</option><?php foreach ($users as $key => $val) echo '<option value="'.$val['id'].'">'.pun_htmlspecialchars($val['username']).'</option>'; ?></select><br /></label>
<label class="conl">Recipient search<br /><select name="recipient"><option value="1">All users</option><?php foreach ($users as $key => $val) echo '<option value="'.$val['id'].'">'.pun_htmlspecialchars($val['username']).'</option>'; ?></select><br /></label>
<p class="clearb">To search by keyword, enter a term or terms to search for. Separate terms with spaces. To search by author or recipient, Choose the user's username from the dropdown box. You may use * as a wildcard for your keywords.</p>
</div>
</fieldset>
</div>
<p><input type="submit" name="search" value="Submit" accesskey="s" /></p>
</form>
</div>
<form id="index" method="post" action="<?php echo $_SERVER['REQUEST_URI'] ?>&foo=bar">
<div class="inform">
<fieldset>
<legend>Start Indexing</legend>
<div class="infldset">
<p class="clearb">The first time you run this script, it is recommended that you let it add an index to your messages table so that you may search much more quickly. Note that the indexing may take an extremely long time, please do not hit Stop in your browser while this is happening. Keep in mind that this need only be run <strong>once</strong>.</p>
<p><input type="submit" name="index" value="Start the indexing!" /></p>
</div>
</fieldset>
</div>
</form>
</div>
</div>
<?php
}
// Note that the script just ends here. The footer will be included by admin_loader.php.
Kato reported an issue with viewing a private message, I did not have an issue. If anyone else tries it and has an issue and can give me access to try and debug it, that would be great (or if you just see the error )
Edit: Small CSS issue has been fixed
Edit2: Added some code when indexing to ensure the index isn't run twice
Edit3: Fixed a small issue that occured in Kato's situation, which seemed to have something to do with MySQL queries in parser.php