Migrating Drupal forums to Vanilla

One of the complaints I've heard fairly often from users of OpenLP is that our forums lack somewhat in usability and features. With this in mind, as part of the OpenLP 2.0 release, I wanted to see if I can move the forums over to some alternative forum software. However, I have a few important prerequisites:

  1. I don't want users to have to re-register on the forums
  2. I want users to be able to move seamlessly between the site and the forums without needing to log in again
  3. I want to move my forum posts across

Current Situation

The web site currently runs on Drupal, which is very extensible, and I had no doubt that it would be able to provide the necessary to perform its side of the job, but I wasn't so sure if any of the forum software would be able to keep its end of the bargain. And so I started my Googling...

The open source heavyweight in this category is phpBB, but, as everybody knows they have security issues coming out of their ears. Actually, from what I've heard, version 3 of phpBB is leaps and bounds ahead of phpBB2 in terms of security. That said, after looking at it again, I still wasn't happy with it. It didn't seem to provide any real integration capabilities.

A few years ago I had also heard of Vanilla Forums, which is not just new forum software, but a new type of forum software. Their addons are simply dropped into the code base to be installed, by far the easiest plugin system yet. I went to go and have a look at Vanilla again, and lo and behold they'd already released version 2.0.

A Solution

It looked to me like Vanilla would be my best bet. However, I still wasn't sure how to provide single sign-on for my users. With this in mind I chatted to a friend of mine who deals with these sorts of web sites on a day-to-day basis, and asked him about my forum dilemma. No problem, he said, I should use the Vanilla Proxyconnect plugin. Just what I needed!

When we originally chatted about this, there was no Drupal module which could provide the integration needed from Drupal's end. My friend was happy to write one for me, but since we didn't get any further with the move to Vanilla at the time of the discussion, he hadn't done much. Fortunately for both of us, someone has written a module, named Orchid, for Drupal since, and I was able to download it and install it in no time.

Problems Encountered

At this point, having a local instance of the site running on my development server, I set up Vanilla on my server, and proceeded to configure the seamless integration. It was pretty easy, and after about 20 minutes I had things working. But I had two problems:

  • If you click Sign Out on the forums, nothing happens
  • If you click Sign In on Vanilla, which takes you to the Drupal login page, the Drupal login page does not take you back to Vanilla

More Googling, and after staring at code for a few hours, I had figured out the problems. Firstly, there was a missing line of code in the Proxyconnect plugin for Vanilla, and secondly, Drupal needs to be told to redirect back to Vanilla.

Fixing The Logout

The logout fix was fairly simple, I just needed to add a line of code similar to the following line to the EntryController_SignOut_Handler function:

Redirect('http://www.yoursite.com/logout.php', 302);

What I ended up with was something like this, which takes the configured logout URL into consideration (based on the login code):

public function EntryController_SignOut_Handler(&$Sender) {
if (!Gdn::Authenticator()->IsPrimary('proxy')) return;
$Redirect = Gdn::Request()->GetValue('HTTP_REFERER');
$SignoutURL = Gdn::Authenticator()->GetURL(Gdn_Authenticator::URL_REMOTE_SIGNOUT, $Redirect);
Redirect($SignoutURL, 302);
}

Fixing The Redirection: Part 1

The Proxyconnect doucmentation suggests telling the CMS that you came from the forums via a simple "?forums=1" type of link. This was not good enough for me, I want the user to be redirected back to the exact page that they were on!

Having a look again at the login and logout code, I had an idea: What if I add a token in the configurable URLs which is replaced with the URL to redirect to?

As you can see in the logout code above, I actually already have the redirect (or 'referer') URL - I just need to use it. With that in mind, I changed the logout method to look like this:

public function EntryController_SignOut_Handler(&$Sender) {
if (!Gdn::Authenticator()->IsPrimary('proxy')) return;
$Redirect = Gdn::Request()->GetValue('HTTP_REFERER');
$SignoutURL = Gdn::Authenticator()->GetURL(Gdn_Authenticator::URL_REMOTE_SIGNOUT, $Redirect);
$SignoutURL = str_replace('{REDIRECT_URL}', urlencode($Redirect), $SignoutURL);
Redirect($SignoutURL, 302);
}

Once I'd done that, I edited the code in the login method, so that it looked like this:

$Redirect = Gdn::Request()->GetValue('HTTP_REFERER');
$SigninURL = Gdn::Authenticator()->GetURL(Gdn_Authenticator::URL_REMOTE_SIGNIN, $Redirect);
$SigninURL = str_replace('{REDIRECT_URL}', urlencode($Redirect), $SigninURL);
Redirect($SigninURL, 302);

Fixing The Redirection: Part 2

Drupal provides a "destination" parameter, which directs any given back to the specified URL, so I thought I'd take advantage of that. As a first course of action, I used the above-mentioned token in the "sign in url" configuration in Vanilla. That did not work as Drupal told me that URL did not exist. It seems that the desintation parameter only works on internal Drupal URLs. Time to make use of Drupal's module hooks system!

Since I was fixing Vanilla integration I decided to just do the Drupal side of things in the Orchid module itself. Orchid already uses the hook_user hook, and specifically deals with the logging in and logging out, so I just tagged along with that, and forced Drupal to redirect if there was a "destination" GET parameter. In the orchid_user function, I added these lines in the bottom of the if statement:

if ($_GET['destination']) {
drupal_goto($_GET['destination']);
}

w00t! My seamless integration works!

Exporting The Data

Unfortunately, that still left me with all my forum posts sitting in Drupal, and nothing in Vanilla. So my next step was to figure out how to export the data from Drupal and then import it into Vanilla.

Some more browsing and Googling brought me to the vanilla2export.php script, which can export data from a number of different forum software packages so that you can import them into Vanilla. Once again, Drupal was unsupported, but after looking at the exporter code and seeing how pluggable it is, I had a Drupal exporter up and running in less than an hour.

The only problem I had with the exporter was that Drupal's user roles don't match well to Vanilla. On top of that, the default roles in Vanilla are deleted when you import data from the vanilla2export.php script. I dropped my Vanilla database and installed Vanilla again. With a new, clean install, I extracted the permissions into an SQL script, and added a few extra tweaks to it, to assign everyone the "Member" role.