MrEyes
03-13-2008, 09:57 AM
Hello all,
The thread title no longer matches the question I have, as originally I didn't know how to acheive what I am trying. However after a little fiddling I am almost there. So I suppose the thread title should be different, unfortunately I can't change it now.
Anyway enough waffle, this is what I am trying to do within a VB cron job:
Select all threads from ForumX that were and started in the last X days where postcount is greater than Y and the status is open.
Then for each of the selected threads move them to ForumY, with a non expiring move message left in ForumX
Then get open threads in ForumX that were started before Z days and lock them.
The following code block is how I have managed to acheive this
<?php
/*
vBulletin Cron Based Auto Move / Lock Threads
A work in progress
*/
error_reporting(E_ALL & ~E_NOTICE);
if (!is_object($vbulletin->db))
{
exit;
}
//vars
$checkForum = 2;
$targetForum = 3;
$threadOpenState = 1;
$afterDate = TIMENOW - (7 * 24 * 60 * 60); //7 days
$lockBeforeDate = TIMENOW - (14 * 24 * 60 * 60); //14 days
$rssIconId = 3;
//select all threads the last 7 days from a specific forum where the reply count
//is > 0 and the thread is marked as fully open (id 1)
$threadsWithReplies = $vbulletin->db->query_read("SELECT
thread.threadid,
thread.title,
thread.lastpost,
thread.forumid,
thread.replycount,
thread.postusername,
thread.postuserid,
thread.lastposter,
thread.views,
thread.iconid
FROM
" . TABLE_PREFIX . "thread as thread
WHERE
thread.replycount > 0
AND
thread.forumid = " . $checkForum . "
AND
thread.open = " . $threadOpenState . "
AND
thread.dateline > " . $afterDate . ""
);
//iterate through the resultset from the DB select query and move each of these
//threads to a different forum
while ($threadinfo = $vbulletin->db->fetch_array($threadsWithReplies))
{
log_cron_action("Moving [". $threadinfo['title'] ."][" . $threadinfo['threadid'] . "] from forum [" . $checkForum . "] to forum [" . $targetForum . "]", $nextitem, $phrased = 0);
//move the thread
$threadman =& datamanager_init('Thread', $vbulletin, ERRTYPE_STANDARD, 'threadpost');
$threadman->set_info('skip_moderator_log', true);
$threadman->set_existing($threadinfo);
$threadman->set('title', $threadinfo['title'], true, false);
$threadman->set('forumid', $targetForum);
$threadman->set('iconid', $rssIconId);
$threadman->save();
unset($threadman);
//create the "moved" message in the original forum
$redirdata = array(
'lastpost' => intval($threadinfo['lastpost']),
'forumid' => intval($threadinfo['forumid']),
'pollid' => intval($threadinfo['threadid']),
'open' => 10,
'replycount' => intval($threadinfo['replycount']),
'postusername' => $threadinfo['postusername'],
'postuserid' => intval($threadinfo['postuserid']),
'lastposter' => $threadinfo['lastposter'],
'dateline' => TIMENOW,
'views' => intval($threadinfo['views']),
'iconid' => intval($threadinfo['iconid']),
'visible' => 1);
$redir =& datamanager_init('Thread', $vbulletin, ERRTYPE_ARRAY, 'threadpost');
foreach (array_keys($redirdata) AS $field)
{
$redir->setr($field, $redirdata["$field"], true, false);
}
//not sure what this if/else statement does, but it is a direct
//copy and paste from postings.php so for now it stays ;)
if (empty($vbulletin->GPC['redirecttitle']))
{
$redir->set('title', $threadinfo['title'], true, false);
}
else
{
$redir->set('title', unhtmlspecialchars($vbulletin->GPC['redirecttitle']));
}
$redir->set('prefixid', $vbulletin->GPC['redirectprefixid']);
$redir->save();
unset($redir);
log_cron_action("Move complete for [". $threadinfo['title'] ."][" . $threadinfo['threadid'] . "] from forum [" . $checkForum . "] to forum [" . $targetForum . "]", $nextitem, $phrased = 0);
$moveActionPerformed = true;
}
unset($threadsWithReplies);
if (!isset($moveActionPerformed))
{
log_cron_action("No items to move", $nextitem, $phrased = 0);
}
//now lock all threads older than $lockBeforeDate
$oldThreads = $vbulletin->db->query_read("SELECT
thread.threadid,
thread.title,
thread.lastpost,
thread.forumid,
thread.replycount,
thread.postusername,
thread.postuserid,
thread.lastposter,
thread.views,
thread.iconid
FROM
" . TABLE_PREFIX . "thread as thread
WHERE
thread.forumid = " . $checkForum . "
AND
thread.open = " . $threadOpenState . "
AND
thread.dateline < " . $lockBeforeDate . ""
);
//iterate through the resultset from the DB select query and lock
//each of these threads
while ($threadinfo = $vbulletin->db->fetch_array($oldThreads))
{
log_cron_action("Locking thread [". $threadinfo['title'] ."][" . $threadinfo['threadid'] . "] from forum [" . $checkForum . "]", $nextitem, $phrased = 0);
//lock the thread
$threadman =& datamanager_init('Thread', $vbulletin, ERRTYPE_STANDARD, 'threadpost');
$threadman->set_info('skip_moderator_log', true);
$threadman->set_existing($threadinfo);
$threadman->set('open', 0);
$threadman->save();
unset($threadman);
$lockActionPerformed = true;
}
unset ($oldThreads);
if (!isset($lockActionPerformed))
{
log_cron_action("No items to lock", $nextitem, $phrased = 0);
}
?>
Problem / Question #1
On my test forum I am moving the thread to an empty forum, after the move has been performed the forumdisplay summary still shows the "Last Post" column as never. How do I update this to show the date/time/poster details of the moved thread? However I suppose that in the real world this doesn't matter so much as the target forum is fairly busy so the "Last Post" will probably be a member post on a different thread.
Problem / Question #2
After I have performed the moves/locks do I need to rebuild any counters? If yes this could be a show stopper as I intend to run this script every 15 minutes and a counter rebuild every time would be a massive hit. For the same reasons I need this to be as optimal as possible, can anybody point out areas where I am performing unnecessary actions? Also on the subject of load, this cron script will be added multiple times for multiple forums (around 5) each of which will run every 15 minutes (staggered) is it worth redesigning the select I am doing to support getting all the posts for all the forums in one select and one cron call?
Problem / Question #3
To explain this some background is needed. I have configured an RSS feed to pull data into vBulletin and post threads in an RSS specific forum. Users do not have access to create threads in this forum but they can reply. If a member replies to an RSS post then they have obviously found the item interesting and worth commenting on, and as such it would be great if this could be highlighted to the rest of the community. Hence the reason for moving it to a "normal" forum. Now here is the problem, if the thread is moved I assume the RSS system will think that that item hasn't been retrieved and will therefore repost the item the next time the feed is checked. Is this right? wrong? I have run some tests and this doesn't seem to happen, I would guess that the RSS Feed subsystem checks if the RSS feed item title is already in the feed target forum and if so ignores it. So this should work as I am leaving a non expiring redirect in this forum if the item is moved. Can anybody confirm this?
So I am now at your mercy, does anybody have any answers/suggestions for these problems/questions?
The thread title no longer matches the question I have, as originally I didn't know how to acheive what I am trying. However after a little fiddling I am almost there. So I suppose the thread title should be different, unfortunately I can't change it now.
Anyway enough waffle, this is what I am trying to do within a VB cron job:
Select all threads from ForumX that were and started in the last X days where postcount is greater than Y and the status is open.
Then for each of the selected threads move them to ForumY, with a non expiring move message left in ForumX
Then get open threads in ForumX that were started before Z days and lock them.
The following code block is how I have managed to acheive this
<?php
/*
vBulletin Cron Based Auto Move / Lock Threads
A work in progress
*/
error_reporting(E_ALL & ~E_NOTICE);
if (!is_object($vbulletin->db))
{
exit;
}
//vars
$checkForum = 2;
$targetForum = 3;
$threadOpenState = 1;
$afterDate = TIMENOW - (7 * 24 * 60 * 60); //7 days
$lockBeforeDate = TIMENOW - (14 * 24 * 60 * 60); //14 days
$rssIconId = 3;
//select all threads the last 7 days from a specific forum where the reply count
//is > 0 and the thread is marked as fully open (id 1)
$threadsWithReplies = $vbulletin->db->query_read("SELECT
thread.threadid,
thread.title,
thread.lastpost,
thread.forumid,
thread.replycount,
thread.postusername,
thread.postuserid,
thread.lastposter,
thread.views,
thread.iconid
FROM
" . TABLE_PREFIX . "thread as thread
WHERE
thread.replycount > 0
AND
thread.forumid = " . $checkForum . "
AND
thread.open = " . $threadOpenState . "
AND
thread.dateline > " . $afterDate . ""
);
//iterate through the resultset from the DB select query and move each of these
//threads to a different forum
while ($threadinfo = $vbulletin->db->fetch_array($threadsWithReplies))
{
log_cron_action("Moving [". $threadinfo['title'] ."][" . $threadinfo['threadid'] . "] from forum [" . $checkForum . "] to forum [" . $targetForum . "]", $nextitem, $phrased = 0);
//move the thread
$threadman =& datamanager_init('Thread', $vbulletin, ERRTYPE_STANDARD, 'threadpost');
$threadman->set_info('skip_moderator_log', true);
$threadman->set_existing($threadinfo);
$threadman->set('title', $threadinfo['title'], true, false);
$threadman->set('forumid', $targetForum);
$threadman->set('iconid', $rssIconId);
$threadman->save();
unset($threadman);
//create the "moved" message in the original forum
$redirdata = array(
'lastpost' => intval($threadinfo['lastpost']),
'forumid' => intval($threadinfo['forumid']),
'pollid' => intval($threadinfo['threadid']),
'open' => 10,
'replycount' => intval($threadinfo['replycount']),
'postusername' => $threadinfo['postusername'],
'postuserid' => intval($threadinfo['postuserid']),
'lastposter' => $threadinfo['lastposter'],
'dateline' => TIMENOW,
'views' => intval($threadinfo['views']),
'iconid' => intval($threadinfo['iconid']),
'visible' => 1);
$redir =& datamanager_init('Thread', $vbulletin, ERRTYPE_ARRAY, 'threadpost');
foreach (array_keys($redirdata) AS $field)
{
$redir->setr($field, $redirdata["$field"], true, false);
}
//not sure what this if/else statement does, but it is a direct
//copy and paste from postings.php so for now it stays ;)
if (empty($vbulletin->GPC['redirecttitle']))
{
$redir->set('title', $threadinfo['title'], true, false);
}
else
{
$redir->set('title', unhtmlspecialchars($vbulletin->GPC['redirecttitle']));
}
$redir->set('prefixid', $vbulletin->GPC['redirectprefixid']);
$redir->save();
unset($redir);
log_cron_action("Move complete for [". $threadinfo['title'] ."][" . $threadinfo['threadid'] . "] from forum [" . $checkForum . "] to forum [" . $targetForum . "]", $nextitem, $phrased = 0);
$moveActionPerformed = true;
}
unset($threadsWithReplies);
if (!isset($moveActionPerformed))
{
log_cron_action("No items to move", $nextitem, $phrased = 0);
}
//now lock all threads older than $lockBeforeDate
$oldThreads = $vbulletin->db->query_read("SELECT
thread.threadid,
thread.title,
thread.lastpost,
thread.forumid,
thread.replycount,
thread.postusername,
thread.postuserid,
thread.lastposter,
thread.views,
thread.iconid
FROM
" . TABLE_PREFIX . "thread as thread
WHERE
thread.forumid = " . $checkForum . "
AND
thread.open = " . $threadOpenState . "
AND
thread.dateline < " . $lockBeforeDate . ""
);
//iterate through the resultset from the DB select query and lock
//each of these threads
while ($threadinfo = $vbulletin->db->fetch_array($oldThreads))
{
log_cron_action("Locking thread [". $threadinfo['title'] ."][" . $threadinfo['threadid'] . "] from forum [" . $checkForum . "]", $nextitem, $phrased = 0);
//lock the thread
$threadman =& datamanager_init('Thread', $vbulletin, ERRTYPE_STANDARD, 'threadpost');
$threadman->set_info('skip_moderator_log', true);
$threadman->set_existing($threadinfo);
$threadman->set('open', 0);
$threadman->save();
unset($threadman);
$lockActionPerformed = true;
}
unset ($oldThreads);
if (!isset($lockActionPerformed))
{
log_cron_action("No items to lock", $nextitem, $phrased = 0);
}
?>
Problem / Question #1
On my test forum I am moving the thread to an empty forum, after the move has been performed the forumdisplay summary still shows the "Last Post" column as never. How do I update this to show the date/time/poster details of the moved thread? However I suppose that in the real world this doesn't matter so much as the target forum is fairly busy so the "Last Post" will probably be a member post on a different thread.
Problem / Question #2
After I have performed the moves/locks do I need to rebuild any counters? If yes this could be a show stopper as I intend to run this script every 15 minutes and a counter rebuild every time would be a massive hit. For the same reasons I need this to be as optimal as possible, can anybody point out areas where I am performing unnecessary actions? Also on the subject of load, this cron script will be added multiple times for multiple forums (around 5) each of which will run every 15 minutes (staggered) is it worth redesigning the select I am doing to support getting all the posts for all the forums in one select and one cron call?
Problem / Question #3
To explain this some background is needed. I have configured an RSS feed to pull data into vBulletin and post threads in an RSS specific forum. Users do not have access to create threads in this forum but they can reply. If a member replies to an RSS post then they have obviously found the item interesting and worth commenting on, and as such it would be great if this could be highlighted to the rest of the community. Hence the reason for moving it to a "normal" forum. Now here is the problem, if the thread is moved I assume the RSS system will think that that item hasn't been retrieved and will therefore repost the item the next time the feed is checked. Is this right? wrong? I have run some tests and this doesn't seem to happen, I would guess that the RSS Feed subsystem checks if the RSS feed item title is already in the feed target forum and if so ignores it. So this should work as I am leaving a non expiring redirect in this forum if the item is moved. Can anybody confirm this?
So I am now at your mercy, does anybody have any answers/suggestions for these problems/questions?