PDA

View Full Version : Visitor Messaging query takes AGES to complete...


DragonBlade
06-11-2009, 10:38 AM
I have a pair of users on my forum that have evidently never heard of IM clients. The converse.php between them is well over 4,000 pages long (estimating that half belong to each of 'em, that's over 20,000 messages a piece at 10 messages per page!).

Anyways, the query now takes AGES to execute--anywhere from 8 seconds (MINIMUM) on up to 20, and sometimes a whole hell of a lot more. I'm fairly sure this ain't my MySQL server settings, either.


The query in question...

(
SELECT
visitormessage.*, visitormessage.dateline AS pmdateline, user.*, visitormessage.ipaddress AS messageipaddress, visitormessage.userid AS profileuserid
,deletionlog.userid AS del_userid, deletionlog.username AS del_username, deletionlog.reason AS del_reason
,avatar.avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar, customavatar.dateline AS avatardateline,customavatar.width AS avwidth,customavatar.height AS avheight, customavatar.width_thumb AS avwidth_thumb, customavatar.height_thumb AS avheight_thumb, filedata_thumb, NOT ISNULL(customavatar.userid) AS hascustom

FROM visitormessage AS visitormessage
LEFT JOIN user AS user ON (visitormessage.postuserid = user.userid)
LEFT JOIN avatar AS avatar ON(avatar.avatarid = user.avatarid) LEFT JOIN customavatar AS customavatar ON(customavatar.userid = user.userid)
LEFT JOIN deletionlog AS deletionlog ON (visitormessage.vmid = deletionlog.primaryid AND deletionlog.type = 'visitormessage')

WHERE visitormessage.userid = 50976 AND visitormessage.postuserid = 35301 AND visitormessage.state IN ('visible','moderation','deleted')

)
UNION
(
SELECT
visitormessage.*, visitormessage.dateline AS pmdateline, user.*, visitormessage.ipaddress AS messageipaddress, visitormessage.userid AS profileuserid
,deletionlog.userid AS del_userid, deletionlog.username AS del_username, deletionlog.reason AS del_reason
,avatar.avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar, customavatar.dateline AS avatardateline,customavatar.width AS avwidth,customavatar.height AS avheight, customavatar.width_thumb AS avwidth_thumb, customavatar.height_thumb AS avheight_thumb, filedata_thumb, NOT ISNULL(customavatar.userid) AS hascustom

FROM visitormessage AS visitormessage
LEFT JOIN user AS user ON (visitormessage.postuserid = user.userid)
LEFT JOIN avatar AS avatar ON(avatar.avatarid = user.avatarid) LEFT JOIN customavatar AS customavatar ON(customavatar.userid = user.userid)
LEFT JOIN deletionlog AS deletionlog ON (visitormessage.vmid = deletionlog.primaryid AND deletionlog.type = 'visitormessage')

WHERE visitormessage.userid = 35301 AND visitormessage.postuserid = 50976 AND visitormessage.state IN ('visible','moderation','deleted')

)
ORDER BY pmdateline DESC
LIMIT 0, 10

Now, I'm guessing it only takes this long because the LIMIT cannot be included on the INSIDE of the individual queries (for the reason that it would screw up page numbers and whatnot, I suppose, I dunno fer sure).

So my question is, what's your advice? Should I just go in and delete several thousand of their VMs? Is there a pruning tool for VMs that I can use? Should I go rant uselessly about this at vB.com? XD



I don't want to disable VMs altogether, but I don't want members to have huuuuuge load times when loading these profiles, nor do I want an 8-20-second query locking up my server. :(

MrEyes
06-11-2009, 12:30 PM
Without rewriting the code that pulls out and renders the VM's I believe the only option you have is to purge out some of the older messages.

Unfortunately I do not think that there is an ACP function for this so unless somebody else can point one out you are going to have to do this in the DB.

I would strongly suggest trying it on an offline backup DB before running it on live.

If you want to be really adventurous you could create an ACP scheduled job to clear out all VM's older than X days every night.

DragonBlade
06-11-2009, 02:13 PM
Hmmm....


I re-wrote the query, actually, and everything SEEMS to be going fine, so far.

Other people can use this, of they want. Word of warning, though--if you have any plugins that make use of the hook query fields or hook query joins for the converse page, you're shit outta luck. :p

Below is the modified script, if anyone wants to test it out. Once I have my troublesome users test it out a bit more, I'll post any corrections I need to make.











<?php
/*================================================= =====================*\
|| ################################################## ################## ||
|| # vBulletin 3.8.0 Beta 2 English - Licence Number (Deleted License Number)
|| # ---------------------------------------------------------------- # ||
|| # Copyright �2000-2008 Jelsoft Enterprises Ltd. All Rights Reserved. ||
|| # This file may not be redistributed in whole or significant part. # ||
|| # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
|| ################################################## ################## ||
\*================================================ ======================*/

// ####################### SET PHP ENVIRONMENT ###########################
error_reporting(E_ALL & ~E_NOTICE);

// #################### DEFINE IMPORTANT CONSTANTS #######################
define('THIS_SCRIPT', 'converse2');
define('CSRF_PROTECTION', true);
define('BYPASS_STYLE_OVERRIDE', 1);

// ################### PRE-CACHE TEMPLATES AND DATA ######################
// get special phrase groups
$phrasegroups = array(
'user',
'posting',
);

// get special data templates from the datastore
$specialtemplates = array(
'smiliecache',
'bbcodecache',
);

// pre-cache templates used by all actions
$globaltemplates = array(
'editor_css',
'editor_clientscript',
'editor_jsoptions_font',
'editor_jsoptions_size',
'memberinfo_block_visitormessaging',
'memberinfo_css',
'memberinfo_usercss',
'memberinfo_visitormessage',
'memberinfo_visitormessage_deleted',
'memberinfo_visitormessage_ignored',
'showthread_quickreply',
'converse',
);

// pre-cache templates used by specific actions
$actiontemplates = array();

// ######################### REQUIRE BACK-END ############################
require_once('./global.php');
require_once(DIR . '/includes/class_bbcode.php');
require_once(DIR . '/includes/class_visitormessage.php');
require_once(DIR . '/includes/functions_visitormessage.php');

// ################################################## #####################
// ######################## START MAIN SCRIPT ############################
// ################################################## #####################

if (!($vbulletin->userinfo['permissions']['forumpermissions'] & $vbulletin->bf_ugp_forumpermissions['canview']) OR !($vbulletin->userinfo['permissions']['genericpermissions'] & $vbulletin->bf_ugp_genericpermissions['canviewmembers']))
{
print_no_permission();
}
if (!($vbulletin->options['socnet'] & $vbulletin->bf_misc_socnet['enable_visitor_messaging']))
{
print_no_permission();
}

$vbulletin->input->clean_array_gpc('r', array(
'u' => TYPE_UINT,
'u2' => TYPE_UINT,
'perpage' => TYPE_UINT,
'pagenumber' => TYPE_UINT,
'showignored' => TYPE_BOOL,
'vmid' => TYPE_UINT
));

($hook = vBulletinHook::fetch_hook('converse_start')) ? eval($hook) : false;

if ($vbulletin->GPC['vmid'])
{
$vminfo = verify_visitormessage($vbulletin->GPC['vmid']);

if (
(
$vminfo['postuserid'] != $vbulletin->GPC['u']
OR $vminfo['userid'] != $vbulletin->GPC['u2']
)
AND
(
$vminfo['userid'] != $vbulletin->GPC['u']
OR $vminfo['postuserid'] != $vbulletin->GPC['u2']
)
)
{
standard_error(fetch_error('invalidid', $vbphrase['visitor_message'], $vbulletin->options['contactuslink']));
}
}

$userinfo = verify_id('user', $vbulletin->GPC['u'], true, true, FETCH_USERINFO_USERCSS | FETCH_USERINFO_ISFRIEND);
$userinfo2 = verify_id('user', $vbulletin->GPC['u2'], true, true, FETCH_USERINFO_USERCSS | FETCH_USERINFO_ISFRIEND);

// $userinfo will never be vbulletin->userinfo
// $userinfo2 may be vbulletin->userinfo
if ($userinfo2['userid'] == $vbulletin->userinfo['userid'])
{
$viewself = true;
}
cache_permissions($userinfo, false);

if (
(
!$userinfo['vm_enable']
AND
!can_moderate(0,'canmoderatevisitormessages')
)
OR
(
$userinfo['vm_contactonly']
AND
!$userinfo['bbuser_iscontact_of_user']
AND
!can_moderate(0,'canmoderatevisitormessages')
)
)
{
print_no_permission();
}

if (
(
!$userinfo2['vm_enable']
AND
(
!can_moderate(0,'canmoderatevisitormessages')
OR
$viewself
)
)
OR
(
$userinfo2['vm_contactonly']
AND
!$userinfo2['bbuser_iscontact_of_user']
AND
!can_moderate(0,'canmoderatevisitormessages')
AND
!$viewself
)
)
{
print_no_permission();
}

// state1/sql1 refers to messages left to u's profile by u2 (which may be bbuserinfo)
// state2/sql2 refers to messages left to u2's profile (which may be bbuserinfo) by u

$sql1 = $sql2 = array();

$state2 = array('visible');
if (fetch_visitor_message_perm('canmoderatevisitormes sages', $userinfo2))
{
$state2[] = 'moderation';
}
if (can_moderate(0,'canmoderatevisitormessages') OR ($viewself AND $vbulletin->userinfo['permissions']['visitormessagepermissions'] & $vbulletin->bf_ugp_visitormessagepermissions['canmanageownprofile']))
{
$state2[] = 'deleted';
$deljoinsql2 = "LEFT JOIN " . TABLE_PREFIX . "deletionlog AS deletionlog ON (visitormessage.vmid = deletionlog.primaryid AND deletionlog.type = 'visitormessage')";
}
else
{
$deljoinsql2 = '';
}

$sql2[] = "visitormessage.userid = $userinfo2[userid]";
$sql2[] = "visitormessage.postuserid = $userinfo[userid]";
$sql2[] = "visitormessage.state IN ('" . implode("','", $state2) . "')";

$state1 = array('visible');
if ($viewself OR fetch_visitor_message_perm('canmoderatevisitormess ages', $userinfo))
{
$state1[] = 'moderation';
}
if (can_moderate(0,'canmoderatevisitormessages'))
{
$state1[] = 'deleted';
$delsql1 = ",deletionlog.userid AS del_userid, deletionlog.username AS del_username, deletionlog.reason AS del_reason";
$deljoinsql1 = "LEFT JOIN " . TABLE_PREFIX . "deletionlog AS deletionlog ON (visitormessage.vmid = deletionlog.primaryid AND deletionlog.type = 'visitormessage')";
}
else if ($deljoinsql2)
{
$delsql1 = ",0 AS del_userid, '' AS del_username, '' AS del_reason";
}

$sql1[] = "visitormessage.userid = $userinfo[userid]";
$sql1[] = "visitormessage.postuserid = $userinfo2[userid]";
$sql1[] = "visitormessage.state IN ('" . implode("','", $state1) . "')";

if (!$vbulletin->GPC['perpage'])
{
$perpage = $vbulletin->options['vm_perpage'];
}
else if ($vbulletin->GPC['perpage'] > $vbulletin->options['vm_maxperpage'])
{
$perpage = $vbulletin->options['vm_maxperpage'];
}
else
{
$perpage = $vbulletin->GPC['perpage'];
}

$hook_query_fields1 = $hook_query_fields2 = $hook_query_joins1 = $hook_query_joins2 = $hook_query_where1 = $hook_query_where2 = '';
($hook = vBulletinHook::fetch_hook('converse_query')) ? eval($hook) : false;



if ($vminfo['vmid'])
{
$getpagenum = $vbulletin->db->query_first("
SELECT COUNT(*) As comments
FROM " . TABLE_PREFIX . "visitormessage AS visitormessage
WHERE (
(" . implode(" AND ", $sql1) . ")
OR (" . implode(" AND ", $sql2) . ")
) AND dateline >= " . $vminfo[dateline]
);
$vbulletin->GPC['pagenumber'] = ceil($getpagenum['comments'] / $perpage);
}

$pagenumber = $vbulletin->GPC['pagenumber'];

do
{
if (!$pagenumber)
{
$pagenumber = 1;
}

$start = ($pagenumber - 1) * $perpage;




$deletes = false;
$state1 = $state2 = array('visible');
if ($viewself OR fetch_visitor_message_perm('canmoderatevisitormess ages', $userinfo)) {$state1[] = 'moderation'; $deletes = true;}
if (fetch_visitor_message_perm('canmoderatevisitormes sages', $userinfo2)) {$state2[] = 'moderation'; $deletes = true;}
if (can_moderate(0,'canmoderatevisitormessages'))
{
$state1[] = 'deleted';
$state2[] = 'deleted';
$deletes = true;
}
$is_self = (can_moderate(0,'canmoderatevisitormessages') OR ($vbulletin->userinfo['permissions']['visitormessagepermissions'] & $vbulletin->bf_ugp_visitormessagepermissions['canmanageownprofile']))
? "visitormessage.userid = " . $vbulletin->userinfo['userid'] : '0';

if ($deletes)
{
$delsql = ", IF($is_self, deletionlog.userid, 0) AS del_userid, IF($is_self, deletionlog.username, 0) AS del_username, IF($is_self, deletionlog.reason, 0) AS del_reason";
$deljoin = "LEFT JOIN " . TABLE_PREFIX . "deletionlog AS deletionlog ON (visitormessage.vmid = deletionlog.primaryid AND deletionlog.type = 'visitormessage')";
}
$wheresql1 = "(visitormessage.userid = $userinfo[userid] AND visitormessage.postuserid = $userinfo2[userid] AND visitormessage.state IN ('" . implode("','", $state1) . "'))";
$wheresql2 = "(visitormessage.userid = $userinfo2[userid] AND visitormessage.postuserid = $userinfo[userid] AND visitormessage.state IN ('" . implode("','", $state2) . "'))";


$messagecount = $db->query_first("SELECT COUNT(*) AS vms FROM " . TABLE_PREFIX . "visitormessage AS visitormessage WHERE $wheresql1 OR $wheresql2");
if ($start >= $messagecount['vms']) {$pagenumber = ceil($messagecount['vms'] / $perpage);}

$messages_query = "SELECT
visitormessage.*, visitormessage.dateline AS pmdateline, user.*, visitormessage.ipaddress AS messageipaddress, visitormessage.userid AS profileuserid
$delsql
" . ($vbulletin->options['avatarenabled'] ? ",avatar.avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar, customavatar.dateline AS avatardateline,customavatar.width AS avwidth,customavatar.height AS avheight" : "") . "
FROM " . TABLE_PREFIX . "visitormessage AS visitormessage
LEFT JOIN " . TABLE_PREFIX . "user AS user ON (visitormessage.postuserid = user.userid)
" . ($vbulletin->options['avatarenabled'] ? "LEFT JOIN " . TABLE_PREFIX . "avatar AS avatar ON(avatar.avatarid = user.avatarid) LEFT JOIN " . TABLE_PREFIX . "customavatar AS customavatar ON(customavatar.userid = user.userid)" : "") . "
$deljoin
WHERE $wheresql1
OR $wheresql2
ORDER BY pmdateline DESC
LIMIT $start, $perpage";

$messages = $db->query_read_slave($messages_query);

}
while ($start >= $messagetotal AND $messagetotal);

$block_data = array(
'messagestart' => $start + 1,
'messageend' => min($start + $perpage, $messagetotal),
'fromconverse' => 1,
);
$prepared = array('vm_total' => $messagetotal);

$bbcode =& new vB_BbCodeParser($vbulletin, fetch_tag_list());
$factory =& new vB_Visitor_MessageFactory($vbulletin, $bbcode, $userinfo2);

$show['conversepage'] = true;

$block_data['messagebits'] = '';
$have_inlinemod = false;
while ($message = $db->fetch_array($messages))
{
if (in_coventry($message['postuserid']) AND !$vbulletin->GPC['showignored'])
{
$message['ignored'] = true;
}
if ($message['profileuserid'] == $vbulletin->userinfo['userid'] AND $message['state'] == 'visible' AND !$message['messageread'])
{
$read_ids[] = $message['vmid'];
}
$response_handler =& $factory->create($message);
$response_handler->converse = false;
$response_handler->cachable = false;
$block_data['messagebits'] .= $response_handler->construct();

if ($show['inlinemod'])
{
$have_inlinemod = true;
}

$block_data['lastcomment'] = !$block_data['lastcomment'] ? $message['dateline'] : $block_data['lastcomment'];
}

// our profile and ids that need read
if (!empty($read_ids))
{
$db->query_write("UPDATE " . TABLE_PREFIX . "visitormessage SET messageread = 1 WHERE vmid IN (" . implode(',', $read_ids) . ")");

build_visitor_message_counters($vbulletin->userinfo['userid']);
}

$dummydata = array();
$show['delete'] = ($have_inlinemod AND fetch_visitor_message_perm('candeletevisitormessag es', $userinfo2));
$show['undelete'] = ($have_inlinemod AND fetch_visitor_message_perm('canundeletevisitormess ages', $userinfo2));
$show['approve'] = ($have_inlinemod AND fetch_visitor_message_perm('canmoderatevisitormess ages', $userinfo2));
$show['inlinemod'] = ($show['delete'] OR $show['undelete'] OR $show['approve']);

// Only allow AJAX QC on the first page
$show['quickcomment'] = (
$userinfo['permissions']['genericpermissions'] & $vbulletin->bf_ugp_genericpermissions['canviewmembers']
AND $vbulletin->options['socnet'] & $vbulletin->bf_misc_socnet['enable_visitor_messaging']
AND $viewself
AND $vbulletin->userinfo['permissions']['visitormessagepermissions'] & $vbulletin->bf_ugp_visitormessagepermissions['canmessageothersprofile']
);
$show['post_visitor_message'] = $show['quickcomment'];

$show['allow_ajax_qc'] = ($pagenumber == 1 AND $messagetotal) ? 1 : 0;
$pagenavbits = array(
"u=$userinfo[userid]",
"u2=$userinfo2[userid]",
);
if ($perpage != $vbulletin->options['vm_perpage'])
{
$pagenavbits[] = "pp=$perpage";
}

if ($vbulletin->GPC['showignored'])
{
$pagenavbits[] = 'showignored=1';
}

$pagenavurl = 'converse.php?' . $vbulletin->session->vars['sessionurl'] . implode('&amp;', $pagenavbits);
$block_data['pagenav'] = construct_page_nav($pagenumber, $perpage, $messagetotal, $pagenavurl, '');

if ($show['quickcomment'])
{
require_once(DIR . '/includes/functions_editor.php');

$stylevar['messagewidth'] = $stylevar['messagewidth_usercp'];
$block_data['editorid'] = construct_edit_toolbar(
'',
false,
'visitormessage',
$vbulletin->options['allowsmilies'],
true,
false,
'qr_small'
);
$block_data['messagearea'] =& $messagearea;
$block_data['clientscript'] = $vBeditTemplate['clientscript'];
}

$navbits = construct_navbits(array(
'member.php?' . $vbulletin->session->vars['sessionurl'] . "u=$userinfo[userid]" => $userinfo['username'],
'' => construct_phrase($vbphrase['conversation_between_x_and_y'], $userinfo['username'], $userinfo2['username']),
));
eval('$navbar = "' . fetch_template('navbar') . '";');

$usercss = construct_usercss($userinfo, $show['usercss_switch']);
$show['usercss_switch'] = ($show['usercss_switch'] AND $vbulletin->userinfo['userid'] != $userinfo['userid']);
construct_usercss_switch($show['usercss_switch'], $usercss_switch_phrase);

($hook = vBulletinHook::fetch_hook('converse_complete')) ? eval($hook) : false;

eval('$memberinfo_css = "' . fetch_template('memberinfo_css') . '";');
eval('$html = "' . fetch_template('memberinfo_block_visitormessaging' ) . '";');
eval('print_output("' . fetch_template('converse') . '");');

/*================================================= =====================*\
|| ################################################## ##################
|| # Downloaded: 08:39, Tue Nov 4th 2008
|| # CVS: $RCSfile$ - $Revision: 16016 $
|| ################################################## ##################
\*================================================ ======================*/
?>

DragonBlade
06-11-2009, 05:27 PM
I'm pleased to report that (with a minor modification) the above script is working MUCH MUCH better than vBulletin's default one. They should hire me, neh? XD

The code with final modification is listed below:





<?php
/*================================================= =====================*\
|| ################################################## ################## ||
|| # vBulletin 3.8.0 Beta 2 English - Licence Number ---------------------- (deleted license number)
|| # ---------------------------------------------------------------- # ||
|| # Copyright �2000-2008 Jelsoft Enterprises Ltd. All Rights Reserved. ||
|| # This file may not be redistributed in whole or significant part. # ||
|| # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
|| # http://www.vbulletin.com | http://www.vbulletin.com/license.html # ||
|| ################################################## ################## ||
\*================================================ ======================*/

// ####################### SET PHP ENVIRONMENT ###########################
error_reporting(E_ALL & ~E_NOTICE);

// #################### DEFINE IMPORTANT CONSTANTS #######################
define('THIS_SCRIPT', 'converse2');
define('CSRF_PROTECTION', true);
define('BYPASS_STYLE_OVERRIDE', 1);

// ################### PRE-CACHE TEMPLATES AND DATA ######################
// get special phrase groups
$phrasegroups = array(
'user',
'posting',
);

// get special data templates from the datastore
$specialtemplates = array(
'smiliecache',
'bbcodecache',
);

// pre-cache templates used by all actions
$globaltemplates = array(
'editor_css',
'editor_clientscript',
'editor_jsoptions_font',
'editor_jsoptions_size',
'memberinfo_block_visitormessaging',
'memberinfo_css',
'memberinfo_usercss',
'memberinfo_visitormessage',
'memberinfo_visitormessage_deleted',
'memberinfo_visitormessage_ignored',
'showthread_quickreply',
'converse',
);

// pre-cache templates used by specific actions
$actiontemplates = array();

// ######################### REQUIRE BACK-END ############################
require_once('./global.php');
require_once(DIR . '/includes/class_bbcode.php');
require_once(DIR . '/includes/class_visitormessage.php');
require_once(DIR . '/includes/functions_visitormessage.php');

// ################################################## #####################
// ######################## START MAIN SCRIPT ############################
// ################################################## #####################

if (!($vbulletin->userinfo['permissions']['forumpermissions'] & $vbulletin->bf_ugp_forumpermissions['canview']) OR !($vbulletin->userinfo['permissions']['genericpermissions'] & $vbulletin->bf_ugp_genericpermissions['canviewmembers']))
{
print_no_permission();
}
if (!($vbulletin->options['socnet'] & $vbulletin->bf_misc_socnet['enable_visitor_messaging']))
{
print_no_permission();
}

$vbulletin->input->clean_array_gpc('r', array(
'u' => TYPE_UINT,
'u2' => TYPE_UINT,
'perpage' => TYPE_UINT,
'pagenumber' => TYPE_UINT,
'showignored' => TYPE_BOOL,
'vmid' => TYPE_UINT
));

($hook = vBulletinHook::fetch_hook('converse_start')) ? eval($hook) : false;

if ($vbulletin->GPC['vmid'])
{
$vminfo = verify_visitormessage($vbulletin->GPC['vmid']);

if (
(
$vminfo['postuserid'] != $vbulletin->GPC['u']
OR $vminfo['userid'] != $vbulletin->GPC['u2']
)
AND
(
$vminfo['userid'] != $vbulletin->GPC['u']
OR $vminfo['postuserid'] != $vbulletin->GPC['u2']
)
)
{
standard_error(fetch_error('invalidid', $vbphrase['visitor_message'], $vbulletin->options['contactuslink']));
}
}

$userinfo = verify_id('user', $vbulletin->GPC['u'], true, true, FETCH_USERINFO_USERCSS | FETCH_USERINFO_ISFRIEND);
$userinfo2 = verify_id('user', $vbulletin->GPC['u2'], true, true, FETCH_USERINFO_USERCSS | FETCH_USERINFO_ISFRIEND);

// $userinfo will never be vbulletin->userinfo
// $userinfo2 may be vbulletin->userinfo
if ($userinfo2['userid'] == $vbulletin->userinfo['userid'])
{
$viewself = true;
}
cache_permissions($userinfo, false);

if (
(
!$userinfo['vm_enable']
AND
!can_moderate(0,'canmoderatevisitormessages')
)
OR
(
$userinfo['vm_contactonly']
AND
!$userinfo['bbuser_iscontact_of_user']
AND
!can_moderate(0,'canmoderatevisitormessages')
)
)
{
print_no_permission();
}

if (
(
!$userinfo2['vm_enable']
AND
(
!can_moderate(0,'canmoderatevisitormessages')
OR
$viewself
)
)
OR
(
$userinfo2['vm_contactonly']
AND
!$userinfo2['bbuser_iscontact_of_user']
AND
!can_moderate(0,'canmoderatevisitormessages')
AND
!$viewself
)
)
{
print_no_permission();
}

// state1/sql1 refers to messages left to u's profile by u2 (which may be bbuserinfo)
// state2/sql2 refers to messages left to u2's profile (which may be bbuserinfo) by u

$sql1 = $sql2 = array();

$state2 = array('visible');
if (fetch_visitor_message_perm('canmoderatevisitormes sages', $userinfo2))
{
$state2[] = 'moderation';
}
if (can_moderate(0,'canmoderatevisitormessages') OR ($viewself AND $vbulletin->userinfo['permissions']['visitormessagepermissions'] & $vbulletin->bf_ugp_visitormessagepermissions['canmanageownprofile']))
{
$state2[] = 'deleted';
$deljoinsql2 = "LEFT JOIN " . TABLE_PREFIX . "deletionlog AS deletionlog ON (visitormessage.vmid = deletionlog.primaryid AND deletionlog.type = 'visitormessage')";
}
else
{
$deljoinsql2 = '';
}

$sql2[] = "visitormessage.userid = $userinfo2[userid]";
$sql2[] = "visitormessage.postuserid = $userinfo[userid]";
$sql2[] = "visitormessage.state IN ('" . implode("','", $state2) . "')";

$state1 = array('visible');
if ($viewself OR fetch_visitor_message_perm('canmoderatevisitormess ages', $userinfo))
{
$state1[] = 'moderation';
}
if (can_moderate(0,'canmoderatevisitormessages'))
{
$state1[] = 'deleted';
$delsql1 = ",deletionlog.userid AS del_userid, deletionlog.username AS del_username, deletionlog.reason AS del_reason";
$deljoinsql1 = "LEFT JOIN " . TABLE_PREFIX . "deletionlog AS deletionlog ON (visitormessage.vmid = deletionlog.primaryid AND deletionlog.type = 'visitormessage')";
}
else if ($deljoinsql2)
{
$delsql1 = ",0 AS del_userid, '' AS del_username, '' AS del_reason";
}

$sql1[] = "visitormessage.userid = $userinfo[userid]";
$sql1[] = "visitormessage.postuserid = $userinfo2[userid]";
$sql1[] = "visitormessage.state IN ('" . implode("','", $state1) . "')";

if (!$vbulletin->GPC['perpage'])
{
$perpage = $vbulletin->options['vm_perpage'];
}
else if ($vbulletin->GPC['perpage'] > $vbulletin->options['vm_maxperpage'])
{
$perpage = $vbulletin->options['vm_maxperpage'];
}
else
{
$perpage = $vbulletin->GPC['perpage'];
}

$hook_query_fields1 = $hook_query_fields2 = $hook_query_joins1 = $hook_query_joins2 = $hook_query_where1 = $hook_query_where2 = '';
($hook = vBulletinHook::fetch_hook('converse_query')) ? eval($hook) : false;



if ($vminfo['vmid'])
{
$getpagenum = $vbulletin->db->query_first("
SELECT COUNT(*) As comments
FROM " . TABLE_PREFIX . "visitormessage AS visitormessage
WHERE (
(" . implode(" AND ", $sql1) . ")
OR (" . implode(" AND ", $sql2) . ")
) AND dateline >= " . $vminfo
);
$vbulletin->GPC['pagenumber'] = ceil($getpagenum['comments'] / $perpage);
}

$pagenumber = $vbulletin->GPC['pagenumber'];

do
{
if (!$pagenumber)
{
$pagenumber = 1;
}

$start = ($pagenumber - 1) * $perpage;




$deletes = false;
$state1 = $state2 = array('visible');
if ($viewself OR fetch_visitor_message_perm('canmoderatevisitormess ages', $userinfo)) {$state1[] = 'moderation'; $deletes = true;}
if (fetch_visitor_message_perm('canmoderatevisitormes sages', $userinfo2)) {$state2[] = 'moderation'; $deletes = true;}
if (can_moderate(0,'canmoderatevisitormessages'))
{
$state1[] = 'deleted';
$state2[] = 'deleted';
$deletes = true;
}
$is_self = (can_moderate(0,'canmoderatevisitormessages') OR ($vbulletin->userinfo['permissions']['visitormessagepermissions'] & $vbulletin->bf_ugp_visitormessagepermissions['canmanageownprofile']))
? "visitormessage.userid = " . $vbulletin->userinfo['userid'] : '0';

if ($deletes)
{
$delsql = ", IF($is_self, deletionlog.userid, 0) AS del_userid, IF($is_self, deletionlog.username, 0) AS del_username, IF($is_self, deletionlog.reason, 0) AS del_reason";
$deljoin = "LEFT JOIN " . TABLE_PREFIX . "deletionlog AS deletionlog ON (visitormessage.vmid = deletionlog.primaryid AND deletionlog.type = 'visitormessage')";
}
$wheresql1 = "(visitormessage.userid = $userinfo[userid] AND visitormessage.postuserid = $userinfo2[userid] AND visitormessage.state IN ('" . implode("','", $state1) . "'))";
$wheresql2 = "(visitormessage.userid = $userinfo2[userid] AND visitormessage.postuserid = $userinfo[userid] AND visitormessage.state IN ('" . implode("','", $state2) . "'))";


$messagecount_results = $db->query_read_slave("SELECT COUNT(*) AS vms FROM " . TABLE_PREFIX . "visitormessage AS visitormessage WHERE $wheresql1 OR $wheresql2");
$messagecount_row = $db->fetch_array($messagecount_results);
$messagetotal = $messagecount_row['vms'];
if ($start >= $messagetotal) {$pagenumber = ceil($messagetotal / $perpage);}

$messages_query = "SELECT
visitormessage.*, visitormessage.dateline AS pmdateline, user.*, visitormessage.ipaddress AS messageipaddress, visitormessage.userid AS profileuserid
$delsql
" . ($vbulletin->options['avatarenabled'] ? ",avatar.avatarpath, NOT ISNULL(customavatar.userid) AS hascustomavatar, customavatar.dateline AS avatardateline,customavatar.width AS avwidth,customavatar.height AS avheight" : "") . "
FROM " . TABLE_PREFIX . "visitormessage AS visitormessage
LEFT JOIN " . TABLE_PREFIX . "user AS user ON (visitormessage.postuserid = user.userid)
" . ($vbulletin->options['avatarenabled'] ? "LEFT JOIN " . TABLE_PREFIX . "avatar AS avatar ON(avatar.avatarid = user.avatarid) LEFT JOIN " . TABLE_PREFIX . "customavatar AS customavatar ON(customavatar.userid = user.userid)" : "") . "
$deljoin
WHERE $wheresql1
OR $wheresql2
ORDER BY pmdateline DESC
LIMIT $start, $perpage";

$messages = $db->query_read_slave($messages_query);

}
while ($start >= $messagetotal AND $messagetotal);

$block_data = array(
'messagestart' => $start + 1,
'messageend' => min($start + $perpage, $messagetotal),
'fromconverse' => 1,
);
$prepared = array('vm_total' => $messagetotal);

$bbcode =& new vB_BbCodeParser($vbulletin, fetch_tag_list());
$factory =& new vB_Visitor_MessageFactory($vbulletin, $bbcode, $userinfo2);

$show['conversepage'] = true;

$block_data['messagebits'] = '';
$have_inlinemod = false;
while ($message = $db->fetch_array($messages))
{
if (in_coventry($message['postuserid']) AND !$vbulletin->GPC['showignored'])
{
$message['ignored'] = true;
}
if ($message['profileuserid'] == $vbulletin->userinfo['userid'] AND $message['state'] == 'visible' AND !$message['messageread'])
{
$read_ids[] = $message['vmid'];
}
$response_handler =& $factory->create($message);
$response_handler->converse = false;
$response_handler->cachable = false;
$block_data['messagebits'] .= $response_handler->construct();

if ($show['inlinemod'])
{
$have_inlinemod = true;
}

$block_data['lastcomment'] = !$block_data['lastcomment'] ? $message['dateline'] : $block_data['lastcomment'];
}

// our profile and ids that need read
if (!empty($read_ids))
{
$db->query_write("UPDATE " . TABLE_PREFIX . "visitormessage SET messageread = 1 WHERE vmid IN (" . implode(',', $read_ids) . ")");

build_visitor_message_counters($vbulletin->userinfo['userid']);
}

$dummydata = array();
$show['delete'] = ($have_inlinemod AND fetch_visitor_message_perm('candeletevisitormessag es', $userinfo2));
$show['undelete'] = ($have_inlinemod AND fetch_visitor_message_perm('canundeletevisitormess ages', $userinfo2));
$show['approve'] = ($have_inlinemod AND fetch_visitor_message_perm('canmoderatevisitormess ages', $userinfo2));
$show['inlinemod'] = ($show['delete'] OR $show['undelete'] OR $show['approve']);

// Only allow AJAX QC on the first page
$show['quickcomment'] = (
$userinfo['permissions']['genericpermissions'] & $vbulletin->bf_ugp_genericpermissions['canviewmembers']
AND $vbulletin->options['socnet'] & $vbulletin->bf_misc_socnet['enable_visitor_messaging']
AND $viewself
AND $vbulletin->userinfo['permissions']['visitormessagepermissions'] & $vbulletin->bf_ugp_visitormessagepermissions['canmessageothersprofile']
);
$show['post_visitor_message'] = $show['quickcomment'];

$show['allow_ajax_qc'] = ($pagenumber == 1 AND $messagetotal) ? 1 : 0;
$pagenavbits = array(
"u=$userinfo[userid]",
"u2=$userinfo2[userid]",
);
if ($perpage != $vbulletin->options['vm_perpage'])
{
$pagenavbits[] = "pp=$perpage";
}

if ($vbulletin->GPC['showignored'])
{
$pagenavbits[] = 'showignored=1';
}

$pagenavurl = 'converse.php?' . $vbulletin->session->vars['sessionurl'] . implode('&amp;', $pagenavbits);
$block_data['pagenav'] = construct_page_nav($pagenumber, $perpage, $messagetotal, $pagenavurl, '');

if ($show['quickcomment'])
{
require_once(DIR . '/includes/functions_editor.php');

$stylevar['messagewidth'] = $stylevar['messagewidth_usercp'];
$block_data['editorid'] = construct_edit_toolbar(
'',
false,
'visitormessage',
$vbulletin->options['allowsmilies'],
true,
false,
'qr_small'
);
$block_data['messagearea'] =& $messagearea;
$block_data['clientscript'] = $vBeditTemplate['clientscript'];
}

$navbits = construct_navbits(array(
'member.php?' . $vbulletin->session->vars['sessionurl'] . "u=$userinfo[userid]" => $userinfo['username'],
'' => construct_phrase($vbphrase['conversation_between_x_and_y'], $userinfo['username'], $userinfo2['username']),
));
eval('$navbar = "' . fetch_template('navbar') . '";');

$usercss = construct_usercss($userinfo, $show['usercss_switch']);
$show['usercss_switch'] = ($show['usercss_switch'] AND $vbulletin->userinfo['userid'] != $userinfo['userid']);
construct_usercss_switch($show['usercss_switch'], $usercss_switch_phrase);

($hook = vBulletinHook::fetch_hook('converse_complete')) ? eval($hook) : false;

eval('$memberinfo_css = "' . fetch_template('memberinfo_css') . '";');
eval('$html = "' . fetch_template('memberinfo_block_visitormessaging' ) . '";');
eval('print_output("' . fetch_template('converse') . '");');

/*================================================= =====================*\
|| ################################################## ##################
|| # Downloaded: 08:39, Tue Nov 4th 2008
|| # CVS: $RCSfile$ - $Revision: 16016 $
|| ################################################## ##################
\*================================================ ======================*/
?>


--------------- Added [DATE]1244744982 at 1244744982 ---------------

Whoops. Er, note that I deleted my license number out of there scripts. XD You can put in your own if you want.