So, I’ve been working on migrating my vBulletin forum to bbPress. I’ll post up later about why I made the move but I’ve come across a bug that I though I would share.
If you’ve done a conversion and found that you are missing some topics then you might be having the same problem as I did. I found that my thread count on the vbulletin forum was about 9,000 posts but after migration I had far fewer in bbPress. I came up with about 2000 topics.
Using google to link to some old threads I indeed got plenty of 404 errors, the conversion had not worked. But, if I searched for the thread name, WordPress search would return all the replies! So the importer was picking up all of the reply posts but it was failing to create a topic for the thread.
Why it happened
The vbulletin converter looks at the threads table and joins this to the posts table where the parentid of the post is 0. This is done as the content required for the topic is actually in the post table but you only want the first post and these don’t have a parent.
However, it turns out that many of my threads joined to posts were there was no parentid = 0 record and therefore nothing was converted. I believe these problem rows were previously imported from my old forum.
I had to do some editing to the vbulletin.php importer. This file contains a series of mapping arrays that tell the importer how to populate fields in bbpress from the source database.
One of the challenges for the importer is to single out all the first posts in a thread as these will become “topics” in bbpress terms, and the other posts are all “replies”.
At certain points the importer joins the vbulletin thread table to the post table and attempts to single out “parent” posts to become topics. I found that some of mine where being droppped due to the following join expression:
'join_expression' => 'USING (threadid) WHERE post.parentid = 0',
This failed for rows that I had migrated from my old forum software into vbulletin. These threads did not have a parentid of zero and the importer simply dropped them during the migration.
So I had to find another way to single these out.
Fortunately the thread table contains a field called firstpostid which holds the id of the first post, the post we want converted into a topic. So by updating the mapping arrays I was able to convert all my topics successfully.
'join_expression' => 'USING (threadid) WHERE post.postid = thread.firstpostid'
If you have the same problem, you’ll want to look for the parentid joins and swap them all out for firstpostid joins. You should end up with something like this:
// Topic Author ip (Stored in postmeta) // Note: We join the 'post' table because 'thread' table does not include topic content. $this->field_map = array( 'from_tablename' => 'post', 'from_fieldname' => 'ipaddress', 'join_tablename' => 'thread', 'join_type' => 'INNER', 'join_expression' => 'USING (threadid) WHERE post.postid = thread.firstpostid', 'to_type' => 'topic', 'to_fieldname' => '_bbp_author_ip' );
There are some other import mappings that are doing the opposite, they want to get only the replies to a thread.
'join_expression' => 'USING (threadid) WHERE post.parentid != 0',
So these will need to be updated to look more like:
'join_expression' => 'USING (threadid) WHERE post.postid != thread.firstpostid',