Forum Replies Created
-
In reply to: WordPress + bbPress Integration 101
Hey all. After much help from reading these forums and tinkering endlessly, I have gotten cross site logins working between WP2.6 and bbpress 0.9 . I don’t know if you’d call it ‘integration’, but it allows a user to log in once and gain access to all appropriate site resources. Although probably not the best solution, what I did is create my own cookie login, which is caught before wordpress or bbpress load, and creates a new user object which is universal to WP and BBPress (and any other webapps you use). It does take a little…alteration…of core WP and BBPress files. I strongly encourage you to make backups before doing this, and proceed at your own risk. It worked for me, but I cannot guarantee that it will fork for you. Also, it took a bit of hacking before I came up with this solution, so it may contain minor errors or accidental omissions as I am having to backtrack to recall what exactly I did.
okay, here goes…
First, we have to configure bbpress to use the wp_users table. That is done in the admin area of bbpress (settings->wordpress integration). Check ‘Show Advanced Database Settings’ and enter your database information for the wordpress install. Also, enter the wordpress database secret code near the top of the settings page.
Next, I created a file in the document root called ‘cookie_login.php’:
<?php
if($_SERVER['REQUEST_URI'] == '/cookie_login.php'){die('Cannot access directly');}
//Initial Setup of Variables
$SECRET_KEY = 'SECRET_KEY_DEFINED_IN_BBPRESS_AND_WP';//use a real secret key
$site_user = false;
//Do the DB thing
$the_db= mysql_connect('SERVER','USER','PASS');
mysql_select_db('DATABASE',$the_db);
//Start Session!
session_set_cookie_params(1800,'/','.SITE.com'); //30 minute session
session_start();
if (isset($_COOKIE['site_cookie'])){ //cookie has been set, proceed to get user info!
$tmp = explode(':',$_COOKIE['site_cookie']); //this will make sense later
$tmpusr = $tmp[0];
$wpid = $tmp[1];
$tmphash = $tmp[2];
$hashShouldBe = md5($tmpusr . $SECRET_KEY . $wpid); //what the hash should be - prevent tampering!
if ($tmphash == $hashShouldBe){
if (isset($_SESSION['user'])){
$site_user = $_SESSION['user'];
}else{
$qry = "SELECT * from wp_users WHERE ID = ".mysql_real_escape_string($wpid,$the_db) . " LIMIT 1";
$result = mysql_query($qry,$the_db);
$site_user = mysql_fetch_assoc($result);
$qry = "SELECT meta_key, meta_value from wp_usermeta where user_id = ".mysql_real_escape_string($wpid,$the_db);//get additional data, just for fun
$resulta = mysql_query($qry,$the_db);
$temp_arr = array();
while ($row = mysql_fetch_assoc($resulta)){
$tmp_value = unserialize($row['meta_value']) ? unserialize($row['meta_value']) : $row['meta_value'];//if it a serialized array, unserialize it. otherwise, dont.
$temp_arr[$row['meta_key']] = $tmp_value;
}
$site_user = $temp_arr + $site_user;
$_SESSION['user'] = (object)$site_user;//Object just out of preference, but doesn't have to be
}
}else{//tsk tsk, bad hash
$_SESSION['user'] = array();
setcookie('site_cookie',$_COOKIE['site_cookie'],time()-9600,'/','.SITE.com');
setcookie('PHPSESSID',$_COOKIE['PHPSESSID'],time()-9600,'/','.SITE.com');
setcookie(session_name(), session_id(), time()-9600, '/');//may be unnecessary...not sure...but can't hurt! (famous last words)
session_destroy();
}
}
if (!isset($_COOKIE['site_cookie']) && isset($_SESSION['user'])){//attempt to gain access?
$_SESSION['user'] = array();
setcookie('site_cookie',$_COOKIE['site_cookie'],time()-9600,'/','.SITE.com');
setcookie('PHPSESSID',$_COOKIE['PHPSESSID'],time()-9600,'/','.SITE.com');
setcookie(session_name(), session_id(), time()-9600, '/');//may be unnecessary...not sure...but can't hurt! (famous last words)
session_destroy();
}
session_write_close();
unset($SECRET_KEY,$hashShouldBe,$tmp,$wpid,$tmphash,$tmpusr,$result,$_SESSION['user'],$resulta,$temp_arr);//burn the evidence!
include ('site_functions.php'); //optional, can hook another file with functions (universal to all sites) to deal with this new user object
?>After I finished the cookie_login.php, I rolled up my sleeves and dove into the WordPress and BBPress core to allow my login to occur.
in the /wp-config.php file, define the cookie domain:
define('COOKIE_DOMAIN', '.SITE.com');
Also, that secret key you used earlier in cookie_login…define it here as well
define('SECRET_KEY', 'Same Key from Earlier. IMPORTANT to make sure it's identical');
Next, I hooked in my cookie_login file to wordpress and bbpress by adding an include to the top of BOTH bb-config.php AND wp-config.php
include $_SERVER['DOCUMENT_ROOT'] . '/cookie_login.php';
To set up the ‘site_cookie’ properly, open up /wp-includes/user.php and find wp_signon function (was the first one for me). At the bottom of the function, after
if ( is_wp_error($user) )
return $user;Add the following:
$hashValue = $credentials['user_login'] . SECRET_KEY . $user->data->ID;
$crossCookieValue = $credentials['user_login'] . ':' . $user->data->ID . ':' . md5($hashValue);
setcookie('site_cookie',$crossCookieValue,0,'/','.SITE.com');
wp_set_auth_cookie($user->ID, $credentials['remember'], $secure_cookie);
do_action('wp_login', $credentials['user_login']);//this may have already been there, don't rememberRemember how I mentioned the site_functions.php which can be included at the bottom of cookie_login.php? That is a perfect place to put the next function, for bbpress login, but it can just as well go inside cookie_login.php itself. The function overwrites the bbpress native wp_validate_auth_cookie function, found in /bb-includes/pluggable.php, with one of our own, which is as follows:
function wp_validate_auth_cookie($cookie = '') {
global $site_user;
if (!isset($site_user->ID)){
return false;
}else{
return $site_user->ID;
}
}This is used internally by bbpress to allow the login to proceed.
Next, open /wp-login.php and find the case: logout section, and add the following right after it:
setcookie('site_cookie',$_COOKIE['site_cookie'],time()-9600,'/','.SITE.com');
setcookie('PHPSESSID',$_COOKIE['PHPSESSID'],time()-9600,'/','.SITE.com');'
Finally, and this may be only applicable for subdomain usage, open /wp-includes/pluggable.php and find the function wp_safe_redirect. Add subdomains you want redirects to in the $allowed_hosts array, for example:$allowed_hosts[]=”bbpress.SITE.com”;
$allowed_hosts[]=”test_wordpres.SITE.com”;`
etc…
That’s all (I think) that I had to do. This is probably not ideal, as there are now two copies of a user when hey login, one defined in our new system and one in the wordpress/bbpress systems; however I found this necessary to have happen since I didn’t want to go through all the core code and edit out mention of $user.
Let me know if this works for you, I hope it was coherant enough. I may have accidentally omitted sections since, as I said before, this is the result of a few weeks of on-and-off tweaks and changes. I can always dig into code and find things I missed if I know what problems are occurring. Also, if anyone is interested, I altered a private messenging system I found which was a little outdated (http://www.pixel2life.com/publish/tutorials/608/simple_private_messaging_system/) to work with this model as well. Users can PM one another from within the wordpress dashboard, and message indicators are noted in the header throughout their visit (in wordpress, bbpress, and other subsites).