Home

Your premium source for custom modification services for phpBB
  logo

HomeForumsBlogMOD ManagerFAQSearchRegisterLogin

Comments September 27, 2009

Post Bump + Cross Posting Prevention

Filed under: Board Management, MOD Writing, phpBB — Dave Rathbun @ 7:24 am CommentsComments (1) 

A long time ago I wrote a MOD for my phpBB2 board that puts a nice red banner at the top of the posting screen if you are getting ready to “bump” your post. Bumping is defined as posting two (or more) times in a row without someone else replying in between, and without waiting 24 hours first. Does it work? From a functional standpoint it certainly does. From a procedural standpoint, not so much.

Implementing the Bump Warning MOD

The MOD was fairly simple to implement. It does require an extra query during the posting process. This query is used to find out if the current poster was also the last person to post in the selected topic. If so, it checks the post time to see if 24 hours have expired. If not, then it sets a value for a template switch which turns on the red warning label on the posting screen. Here’s the code from posting.php.

// BEGIN Bump Warning 1.0.0 (phpBBDoctor.com)
if ($mode == 'reply')
{
        $sql = 'SELECT  p.post_id
                ,       p.poster_id
                ,       p.post_time
                FROM    ' . POSTS_TABLE . ' p
                ,       ' . TOPICS_TABLE . ' t
                WHERE   t.topic_id = ' . $topic_id . '
                AND     p.post_id = t.topic_last_post_id+0';

        if (!($result = $db->sql_query($sql)))
        {
                message_die(GENERAL_ERROR, 'Invalid cursor getting last poster', '', '', '', $sql);
        }
        $check = $db->sql_fetchrow($result);
        $last_post_id = $check['post_id'];
        $db->sql_freeresult($result);

        if ( ($check['poster_id'] == $userdata['user_id']) && ($check['post_time'] > time() - (86400)) )
        {
                $template->assign_block_vars('switch_bump_warning', array(
                        'U_EDIT_PRIOR_POST' => append_sid("posting.$phpEx?mode=editpost&p=$last_post_id")
                        ));
        }
}
// END Bump Warning 1.0.0 (phpBBDoctor.com)

Then of course in the template file I have the switch defined.

<!-- BEGIN switch_bump_warning -->
<tr>
<td class="favrow_red" width="22%" height="35"><span class="gen"><strong>Bump Warning</strong></span></td>
<td class="favrow_red" width="78%"><span class="gen">It appears that you were the last person to post in this topic and 24 hours has not yet elapsed. Please do not reply to your post unless you have new information to add. You may also <a href="{switch_bump_warning.U_EDIT_PRIOR_POST}" class="gen">edit your prior post</a> since nobody has replied yet. Thanks.</td>
</tr>
<!-- END switch_bump_warning -->

This is all well and good, but it seems that some people can be blind. Somehow the red banner across the top of the screen isn’t enough to let them know they’re doing something that I don’t want them to do. I even give them a link to edit the prior post instead of adding a new one…

Post Bump Screen Shot

Since I have asked nicely and they’re still bumping posts, what do I do next?

Duplicate Post Prevention

There are two kinds of post bumps that I typically see. The first kind is what I have described above where the person is simply ignoring my request to not do what he or she is about to do. The second kind is also common and is not really something I can blame a user for. At times the Internet gets slow, and the posting process times out. It may also be that there are several hundred people watching a topic and it takes time to send those emails. (Something else I want to modify; I want to set up a job-queue to handle this process so the poster doesn’t pay a penalty for that during their posting process.) The bottom line is that sometimes a post times out, so the user resubmits. And resubmits. And when they’re done, there are two (or three or more) posts in a row that contain the same text.

So tonight I am starting to test a new feature. I am supplementing my bump “warning” with a bump “rejection” as well. The bump rejection does not prevent a legitimate post bump, but it will catch users that enter the same post twice due to the time-out issue I described above. As an added bonus, this new code will also detect a cross-posted topic and prevent that as well.

To make this change I opened includes/functions_post.php and added code to the Flood Control section. As this is very preliminary I am not using any language strings. That being said, here’s the code.

// Cross-post capture
$sql = 'select  post_text
        ,       p.post_id
        ,       p.topic_id
        from    ' . POSTS_TEXT_TABLE . ' pt
        ,       ' . POSTS_TABLE . ' p
        where   p.poster_id = ' . $userdata['user_id'] . '
        AND     p.post_id = pt.post_id
        ORDER BY p.post_id desc limit 3';

if (!($result = $db->sql_query($sql) ) )
{
        message_die(GENERAL_ERROR, 'Invalid cursor while checking for cross posts');
}

while ($cp_row = $db->sql_fetchrow($result))
{
        if (soundex($post_message) == soundex($cp_row['post_text']))
        {
                if ($topic_id == $cp_row['topic_id'])
                {
                        message_die(GENERAL_MESSAGE, 'You are attempting to post the same item twice. It is possible that your browser timed-out on your prior post submission. If you think this is an error, please click the "back" button on your browser and review your post text. Otherwise please <a href="' . append_sid('viewtopic.php?p=' . $cp_row['post_id'] . '#'      . $cp_row['post_id']) .'">Click      Here</a> to review your   prior post.');
                }
                else
                {
                        message_die(GENERAL_MESSAGE, 'You seem to be posting the same text in two different topics. Please do not do this, as it is called cross-posting and it does not help our board. Cross-posting can lead to fragmented discussions and extra work for people that want to help you. Please pick only one forum to post your question. If needed the topic can be moved to a different forum later. Thanks for your help in this matter. Please <a href="' . append_sid('viewtopic.php?t=' . $cp_row['topic_id'])      .'">Click Here</a> to return to        your prior topic.');
                }
        }
}
$db->sql_freeresult($result);

The query here is simple. Go get the last three posts by this user. Other than the overhead of reading the large text field into memory this query should be extremely quick. Next, check to see if the text of any of their prior posts is essentially identical to the post they are about to enter. In the case of the browser time-out situation I described earlier the post would be 100% identical. In the case of a cross-post attempt I would expect the text to be the same, as most people type up the post and then copy/paste to enter the next. By using the soundex() function on the data I can ignore spacing and punctuation differences.

If the post text is the same, the next step is to see if the post is going into the same topic or not. A time-out warning is issued if the user is entering the same text for two posts in a row in the same topic. If they’re not posting in the same topic, then a cross-post warning is issued instead.

I am testing this now, and hope to put it into production next week.

Summary

Does this MOD impact the user experience? Yes, it does. But I am willing to do that in this case to “train” the user how to be a better board citizen. There won’t be any more post duplicates because of time-out issues, and cross-posting should be cut down as well. Both of those are desirable outcomes. If my users complain to much, I may consider reworking it. Then again, all I am doing is adding code to help them follow the rules.

Personally, I’m looking forward to no more duplicate (or triplicate) posts as well as seeing what new and creative ways people find to get around the cross-posting rejection. 8-)

1 Comment

  1. I’ve solved the problem by using nonces around the site. Each post form creates a nonce, and inserts it into the database. Each successful post action checks for the nonce, and if found, deletes it. Else, the post is rejected. If my site got bigger, I would store nonces using memcached instead of in the db.

    Comment by Dog Cow — September 27, 2009 @ 2:35 pm

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress