After deciding to use vBulletin for Joomlaya.com, I bought my first copy of vBulletin (my first exposure to the vBulletin source code) and installed it together with the great vBridge component from Marko Schmuck's (aka Predator). I followed the excellent documentation written by Ken McDonald to the letter. vBridge took me 90% of the way. However, vBridge did not do everything the way I wanted. This is mostly because I have some special and picky requirements. So, it was time to dive into the source code?
What I did is tailored to my specific requirements. Keep this in mind when reading the rest of the article. I want to have a tight but clean integration. I wanted to follow the mission set by vBridge: Keep the integration clean so that later on, if you want to split them, you can.
This guide is intended for developers. If you are not a coder, you have a couple options. One, you can use the current release of vBridge as is or wait for the next release of vBridge. Or two, you can pay some developer to do a custom integration for you.
Before following instructions in this guide, you should have installed vBridge first, apply the file patches, but NOT the vBulletin template patch. Having vBridge in place makes things so much easier when looking at the source code, it marks all the places where code changes are needed.
Let's look at each aspects of the integration in turn: user migration, registration, activation, login, logout, profile updates, lost password requests, user administration and lastly visual integration.

User Migration
As I already have a large number of users in Mambo, keeping them intact is absolutely essential. I do not want to reset their passwords. I also do not want to overwrite their Mambo encrypted passwords with vBulletin encrypted passwords. This defeats the claims that I can separate Mambo and vBulletin later. I want to keep the passwords in Mambo they way Mambo likes it, and keep passwords in vBulletin the way vBulletin likes it. Having made this decision on the database structure changed everything else for the integration.

I made my own custom user migration script. See cz_mambo2vb.php in the attached zip file. This script simply populates vBulletin database with users from Mambo, it does not change the Mambo user tables.

Caution: DELETE this script after you are done with it! Or keep it in a protect area only accessible by yourself.

Users Registration
I want all the users to register through vBulletin, simply because vBulletin has a more powerful registration interface, with features like COPPA, Captcha verification, resend activation code, etc.

I made a change to the mambo core file, registration.php (included in the attached zip) to redirect all registration to vBulletin. Why didn't I just use the login module supplied with vBridge. The hack in the core is more reliable. For example, when a user get the message "not authorized to view this resource, please register?" and clicks on the register link, this hack takes care of forwarding them to the vBulletin registration page.

The code change in registration.php also took care of user lost password forwarding to vBulletin.

Now let's look at how vBulletin handles the registrations. First, you need to copy the file mambo_helper.php into your vBulletin directory. This file provides mambo related helper functions for vBulletin. I felt keeping the code is a separate file makes upgrading vBulletin later easier, just slightly.

In vBulletin's register.php file (not included in the zip. as vBulletin is a commercial product, I am not sure if I am allowed to distribute their files).
Add the line:
require_once('./mambo_helper.php');


Find the lines:
$salt = fetch_user_salt(3);
if (strlen($_POST['password_md5']) == 32)
{
$hashedpassword = md5($_POST['password_md5'] . $salt);

}
else
{
$hashedpassword = md5(md5($_POST['password']) . $salt);

}


Change it to:
$salt = fetch_user_salt(3);
if (strlen($_POST['password_md5']) == 32)
{
$hashedpassword = md5($_POST['password_md5'] . $salt);
// CZVB WH-
$mambo_password = $_POST['password_md5'];
// CZVB WH-

}
else
{
$hashedpassword = md5(md5($_POST['password']) . $salt);
// CZVB WH-
$mambo_password = md5($_POST['password']);
// CZVB WH-

}


Find the lines:
// insert record into password history
$DB_site->query("INSERT INTO " . TABLE_PREFIX . "passwordhistory (userid, password, passworddate) VALUES ($userid, '" . addslashes($hashedpassword) . "', NOW())");

$bbuserinfo['userid'] = $userid;


Change it to:
// insert record into password history
$DB_site->query("INSERT INTO " . TABLE_PREFIX . "passwordhistory (userid, password, passworddate) VALUES ($userid, '" . addslashes($hashedpassword) . "', NOW())");
$bbuserinfo['userid'] = $userid;

//
mambo_post_register(
addslashes(htmlspecialchars_uni($_POST['username'])),
addslashes($mambo_password),
addslashes(htmlspecialchars_uni($_POST['email'])),
$newusergroupid, $userid);

//

Note: I replaced some of the code from vBridge with my own code above. I added to all of my comments the suffix "WH-". This simply makes it easier for me to search for all the places where code is changed.

This takes care of registration and correctly populate mambo user table with the password the way Mambo likes it.

User Activation
In the same register.php in the vBulletin directory,
Find the lines:
// ### DO THE UG/TITLE UPDATE ###
$DB_site->query("UPDATE " . TABLE_PREFIX . "user SET usergroupid=$user[usergroupid] $dotitle WHERE userid=$u");


Change it to:
// ### DO THE UG/TITLE UPDATE ###
$DB_site->query("UPDATE " . TABLE_PREFIX . "user SET usergroupid=$user[usergroupid] $dotitle WHERE userid=$u");

//
$DB_site->query("UPDATE " . MOS_PREFIX . "users SET block='0', activation='' WHERE username='" . $userinfo['username'] . "'");
//


Note: this is another replacement of the vBridge code. Namely, I use the username to lookup the users in Mambo, instead of the added vb_userid column by vBridge.

That takes care of user activation.

User Login and Logout
Of course, users need to be able to login and logout from either vBulletin or Joomla. The way vBridge handles vBulletin logins is forwarding all login requests to Mambo (with a change in the vBulletin login template), and then changed the mambo login code to do verification the way vBulletin does it, and then forward users back to vBulletin when done.

I want to keep Mambo and vBulletin do user verification the way they used to and just set each others' cookies/sessions. This way, Mambo stays in Mambo, and vBulletin stays in vBulletin. No redirects are done, but login in one areas automatically logins you into the other area.

On the Mambo side, you need to modify the /includes/mambo.php file as attached in the zip file. The main changes are in the login/logout functions.

On the vBulletin side (again, not included in the zip), find the file login.php,

Find the line:
eval(print_standard_error('error_cookieclear'));


Change it to:
//
$lifetime = time() - 1800;
setcookie( "usercookie[username]", " ", $lifetime, "/" );
setcookie( "usercookie[password]", " ", $lifetime, "/" );
setcookie( "usercookie", " ", $lifetime, "/" );
setcookie( "sessioncookie", " ", $lifetime, "/" );
@session_destroy();
//

eval(print_standard_error('error_cookieclear'));


Find the line:
// admin control panel or upgrade script login


Change it to:
// CZ mambo integration code WH-
mambo_post_login($bbuserinfo['username']);

// admin control panel or upgrade script login


Find the line:
eval(fetch_email_phrases('resetpw', $userinfo['languageid']));


Change it to:
//
$sql = "UPDATE " . MOS_PREFIX. "users SET password='"
. addslashes(md5($newpassword)) . "' WHERE username='$userinfo[username]'";
$DB_site->query($sql);
//
eval(fetch_email_phrases('resetpw', $userinfo['languageid']));


This also takes are of lost password and resetting passwords.

User Profile Updates
Users can update their profile in vBulletin, when they do, the corresponding entries needs to be updated in the Mambo tables. Open the file profile.php in your vBulletin installation,

Find the section:
if (strlen($newpassword_md5) == 32)
{
$newpassword = md5($newpassword_md5 . $bbuserinfo['salt']);

}
else
{
$newpassword = md5(md5($newpassword) . $bbuserinfo['salt']);

}


Change it to:
if (strlen($newpassword_md5) == 32)
{
//
$new_mambo_password = $newpassword_md5;
//
$newpassword = md5($newpassword_md5 . $bbuserinfo['salt']);

}
else
{
//
$new_mambo_password = md5($newpassword);
//
$newpassword = md5(md5($newpassword) . $bbuserinfo['salt']);

}


Find the section:
if (!empty($newpassword))
?
?
if ($newemailaddress)


Make it look like:
if (!empty($newpassword))
{
// insert record into password history
$DB_site->query("INSERT INTO " . TABLE_PREFIX . "passwordhistory (userid, password, passworddate) VALUES ($bbuserinfo[userid], '" . addslashes($newpassword) . "', NOW())");

//

if (!empty($newmbemail)) {
$newmbpassword = "password = '" . addslashes($new_mambo_password) . "',";

} else {
$newmbpassword = "password = '" . addslashes($new_mambo_password) . "'";

}
//


$newpassword = "password = '" . addslashes($newpassword) . "', passworddate = NOW(),";

} else {
$newpassword = '';
//
$newmbpassword = '';
//

}

if ($newpassword OR $newemail)
{
$DB_site->query("UPDATE " . TABLE_PREFIX . "user SET $newpassword $newemail usergroupid = " . intval($bbuserinfo['usergroupid']) . " WHERE userid = $bbuserinfo[userid]");

//
$DB_site->query("UPDATE " . MOS_PREFIX . "users SET $newmbpassword $newmbemail WHERE username='$bbuserinfo[username]'");
//

}

if ($newemailaddress)


That should've token care of everything as far as the user integration is concerned.

What about User Administration?
I didn't forget. But I decided it was not necessary. You can set users to different levels/groups independently in Mambo or vBulletin. Eg, you can have a user who is a publisher in Mambo and just a regular user in vBulletin. If you want to manually ban, activate, delete a user, you need to do it in both Mambo admin and vBulletin admin. I am betting/hoping I will spend less time manually ban users than to write code to handle the bridging.

What about Visual/Template Integration?
I didn't forget about this either. As of now, there is no automatic visual integration. Copy the mambo header into the vBulletin header template; change the styles, css to match the rest of the site.
Questions
If you have any questions, please ask in the forums, instead of contacting me directly. I do not plan to support this "release" (if I can even call it a release).


I have given everything I got to Predator, the maker of vBridge, now also a member of the Joomla! Core Team. Congrats Marko! (if you are reading this). You should make this bridge part of the Joomla 1.1 core, or even better embed vBulletin completely into Joomla! Ok, got a little carried away there, forgetting vBulletin is a commercial package.

Happy integrating!
{mos_vbridge_discuss:31}