Newer
Older
<?php
* Set the necessary cookies for the user to be logged into the forum.
*
* Frontend cookie names:
* - lastvisit, lastactivity, sessionhash
* Backend cookie names:
* - cpsession, userid, password
*
* However, in all cases the cookiedomain is NOT prefixed with a dot unless
* cookie domain has not been manually altered to either a suggested value or
* custom value in vB's settings.
function drupalvb_set_login_cookies($userid) {
// Load required vB user data.
$vbuser = drupalvb_db_query("SELECT userid, password, salt FROM {user} WHERE userid = :userid", array(":userid" => $userid))->fetchAssoc();
if (!$vbuser) {
return FALSE;
}
Ed Brown
committed
$vb_options = drupalvb_get_options();
$cookie_prefix = drupalvb_get_cookieprefix();
$cookie_path = $vb_options['cookiepath'];
$now = time();
$expire = $now + (@ini_get('session.cookie_lifetime') ? ini_get('session.cookie_lifetime') : 60 * 60 * 24 * 365);
$vb_cookie_domain = (!empty($vb_options['cookiedomain']) ? $vb_options['cookiedomain'] : $GLOBALS['cookie_domain']);
// Per RFC 2109, cookie domains must contain at least one dot other than the
// first. For hosts such as 'localhost' or IP Addresses we don't set a cookie domain.
// @see conf_init()
if (!(count(explode('.', $vb_cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $vb_cookie_domain)))) {
$vb_cookie_domain = '';
}
Daniel Kudwien
committed
// Clear out old session (if available).
if (!empty($_COOKIE[$cookie_prefix .'sessionhash'])) {
drupalvb_db_query("DELETE FROM {session} WHERE sessionhash = :hash", array(":hash" => $_COOKIE[$cookie_prefix .'sessionhash']));
Daniel Kudwien
committed
}
// Setup user session.
$ip = implode('.', array_slice(explode('.', drupalvb_get_ip()), 0, 4 - $vb_options['ipcheck']));
$idhash = md5($_SERVER['HTTP_USER_AGENT'] . $ip);
Daniel Kudwien
committed
$sessionhash = md5($now . request_uri() . $idhash . $_SERVER['REMOTE_ADDR'] . user_password(6));
$browserstring = substr(trim($_SERVER['HTTP_USER_AGENT']), 0, 100);
drupalvb_db_query("REPLACE INTO {session} (sessionhash, userid, host, idhash, lastactivity, location, useragent, loggedin) VALUES (:hash, :userid, :host, :idhash, :lastactivity, :location, :useragent, :loggedin)", array(":hash" => $sessionhash, ":userid" => $vbuser['userid'], ":host" => substr($_SERVER['REMOTE_ADDR'], 0, 15), ":idhash" => $idhash, ":lastactivity" => $now, ":location" => '/forum/', ":useragent" => $browserstring, ":loggedin" => 2));
// Setup cookies.
setcookie($cookie_prefix .'sessionhash', $sessionhash, $expire, $cookie_path, $vb_cookie_domain);
setcookie($cookie_prefix .'lastvisit', $now, $expire, $cookie_path, $vb_cookie_domain);
setcookie($cookie_prefix .'lastactivity', $now, $expire, $cookie_path, $vb_cookie_domain);
setcookie($cookie_prefix .'userid', $vbuser['userid'], $expire, $cookie_path, $vb_cookie_domain);
setcookie($cookie_prefix .'password', md5($vbuser['password'] . variable_get('drupalvb_license', '')), $expire, $cookie_path, $vb_cookie_domain);
return TRUE;
}
Daniel Kudwien
committed
*
* @see drupalvb_logout(), drupalvb_user_logout()
Daniel Kudwien
committed
function drupalvb_clear_cookies($userid = NULL) {
Ed Brown
committed
$vb_options = drupalvb_get_options();
$cookie_prefix = drupalvb_get_cookieprefix();
Daniel Kudwien
committed
$expire = time() - 86400;
$vb_cookie_domain = (!empty($vb_options['cookiedomain']) ? $vb_options['cookiedomain'] : $GLOBALS['cookie_domain']);
// Per RFC 2109, cookie domains must contain at least one dot other than the
// first. For hosts such as 'localhost' or IP Addresses we don't set a cookie domain.
// @see conf_init()
if (!(count(explode('.', $vb_cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $vb_cookie_domain)))) {
$vb_cookie_domain = '';
}
Daniel Kudwien
committed
// @todo Without a vB user id, we cannot delete the session, so vBulletin
// will automatically authenticate again. We badly need a solution here,
// since this is the cause for broken session handling. Proposal: Use
// drupalvb_get_ip() to count the # of sessions; if there exactly one,
// kill it.
Ed Brown
committed
// @ttkaminski's suggestion - validate the sessionhash and userid from the
// cookies against the vBulletin session table. If it matches, then kill
// the session.
Daniel Kudwien
committed
if (!empty($userid)) {
drupalvb_db_query("DELETE FROM {session} WHERE userid = :userid", array(':userid' => $userid));
drupalvb_db_query("UPDATE {user} SET lastvisit = :time WHERE userid = :userid", array(":time" => time(), ":userid" => $userid));
Daniel Kudwien
committed
}
setcookie($cookie_prefix .'sessionhash', '', $expire, $cookie_path, $vb_cookie_domain);
setcookie($cookie_prefix .'lastvisit', '', $expire, $cookie_path, $vb_cookie_domain);
setcookie($cookie_prefix .'lastactivity', '', $expire, $cookie_path, $vb_cookie_domain);
setcookie($cookie_prefix .'userid', '', $expire, $cookie_path, $vb_cookie_domain);
setcookie($cookie_prefix .'password', '', $expire, $cookie_path, $vb_cookie_domain);
}
Daniel Kudwien
committed
*
* @todo Duplicate of ip_address() in D6+ ?
Daniel Kudwien
committed
$ip = $_SERVER['REMOTE_ADDR'];
Daniel Kudwien
committed
$ip = $_SERVER['HTTP_CLIENT_IP'];
elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR'], $matches)) {
Daniel Kudwien
committed
// Make sure we don't pick up an internal IP defined by RFC1918.
foreach ($matches[0] as $match) {
if (!preg_match("#^(10|172\.16|192\.168)\.#", $match)) {
$ip = $match;
elseif (isset($_SERVER['HTTP_FROM'])) {
Daniel Kudwien
committed
$ip = $_SERVER['HTTP_FROM'];
Daniel Kudwien
committed
return $ip;
}
* Create a user in vBulletin.
*
* @param object $account
* A Drupal user account.
* @param array $edit
* Form values provided by hook_user().
function drupalvb_create_user($account, $edit) {
// Ensure we are not duplicating a user.
Ed Brown
committed
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
$userid = drupalvb_db_select("user","u")
->fields("u", array("userid") )
->condition("username", drupalvb_htmlspecialchars($edit['name']) )
->execute()
->fetchColumn(0);
if(!$userid) {
$salt = '';
for ($i = 0; $i < 3; $i++) {
$salt .= chr(rand(32, 126));
}
// Note: Password is already hashed during user export.
if (isset($edit['md5pass'])) {
$passhash = md5($edit['md5pass'] . $salt);
}
else {
$passhash = md5(md5($edit['pass']) . $salt);
}
$time = $account->created;
$passdate = date('Y-m-d', $time);
$joindate = $time;
// Attempt to grab the user title from the database.
$result = drupalvb_db_query("SELECT title FROM {usertitle} WHERE minposts = 0");
if ($resarray = $result->fetchAssoc()) {
$usertitle = $resarray['title'];
}
else {
$usertitle = 'Junior Member';
}
// Divide timezone by 3600, since vBulletin stores hours.
$timezone = variable_get('date_default_timezone', 0);
$timezone = ($timezone != 0 ? $timezone / 3600 : 0);
// Default new user options: I got these by setting up a new user how I
// wanted and looking in the database to see what options were set for him.
$options = variable_get('drupalvb_default_options', '3415');
// Default usergroup id.
$usergroupid = variable_get('drupalvb_default_usergroup', '2');
$lid = drupalvb_get_languageid();
if (!isset($lid)) {
$lid = 1;
}
// Insert user to vBulletin
$userid = drupalvb_db_insert("user")
->fields( array(
"username" => drupalvb_htmlspecialchars($edit['name']),
"usergroupid" => $usergroupid,
"password" => $passhash,
"passworddate" => $passdate,
"usertitle" => $usertitle,
"email" => $account->mail,
"salt" => $salt,
"languageid" => 1,
"timezoneoffset" => $timezone,
"joindate" => $joindate,
"lastvisit" => time(),
"lastactivity" => time(),
"options" => $options
))->execute();
$rr = drupalvb_db_query("SELECT * FROM {userfield} WHERE userid=1");
$fields = $rr->fetchAssoc();
foreach($fields as $f => $v) $fields[$f] = '';
$fields['userid'] = $userid;
drupalvb_db_insert("userfield")->fields($fields)->execute();
$rr = drupalvb_db_query("SELECT * FROM {usertextfield} WHERE userid=1");
$fields = $rr->fetchAssoc();
foreach($fields as $f => $v) $fields[$f] = '';
$fields['userid'] = $userid;
drupalvb_db_insert("usertextfield")->fields($fields)->execute();
Daniel Kudwien
committed
// Insert new user into mapping table.
drupalvb_set_mapping($account->uid, $userid);
Daniel Kudwien
committed
// Return userid of newly created account.
return $userid;
}
* Update a user in vBulletin.
Ed Brown
committed
function drupalvb_update_user($account, $edit) {
$fields = $values = array();
Ryan Szrama
committed
foreach ($edit as $field => $value) {
if (empty($value)) {
continue;
}
switch ($field) {
case 'name':
$fields[] = "username = :name";
$values[':name'] = drupalvb_htmlspecialchars($value);
break;
Ed Brown
committed
case 'current_pass':
$fields[] = "password = :password";
Ed Brown
committed
$values[':password'] = md5(md5($value) . $edit['salt']);
$fields[] = "salt = :salt";
$values[':salt'] = $edit['salt'];
$fields[] = "passworddate = :date";
$values[':date'] = date('Y-m-d', time());
break;
case 'mail':
$fields[] = "email = :email";
$values[':email'] = $value;
break;
case 'language':
$fields[] = "languageid = :lid";
break;
}
}
$fields[] = 'lastactivity = :activity';
$values[':activity'] = time();
Daniel Kudwien
committed
// Ensure this user exists in the mapping table.
// When integrating an existing installation, the mapping may not yet exist.
Ed Brown
committed
if (isset($edit['userid'])) {
$userid = $edit['userid'];
}
else {
$userid = drupalvb_db_query("SELECT userid FROM {user} WHERE username = :name", array(':name' => drupalvb_htmlspecialchars($account->name)))->fetchField();
}
drupalvb_set_mapping($account->uid, $userid);
Ed Brown
committed
$values[':userid'] = $userid;
drupalvb_db_query("UPDATE {user} SET " . implode(', ', $fields) . " WHERE userid=:userid", $values);
}
/**
* Ensure that a mapping between two existing user accounts exists.
*
* @param $uid
* A Drupal user id.
* @param $userid
* A vBulletin user id.
*/
function drupalvb_set_mapping($uid, $userid) {
db_query("INSERT IGNORE INTO {drupalvb_users} (uid, userid) VALUES (:uid, :userid)", array(':uid' => $uid, ':userid' => $userid));
/**
* Export all drupal users to vBulletin.
*/
function drupalvb_export_drupal_users() {
module_load_include('inc', 'drupalvb');
Ed Brown
committed
$result = db_query("SELECT * FROM {users} WHERE uid>0 ORDER BY uid");
foreach ($result as $user) {
// Let create/update functions know that passwords are hashed already.
$user->md5pass = $user->pass;
if (!drupalvb_create_user($user, (array)$user)) {
// Username already exists, update email and password only.
// Case insensitive username is required to detect collisions.
Ed Brown
committed
$vbuser = drupalvb_db_query("SELECT salt,userid FROM {user} WHERE LOWER(username) = LOWER(:name)", array(':name' => drupalvb_htmlspecialchars($user->name)))->fetchAssoc();
drupalvb_update_user($user, array_merge((array)$user, $vbuser));
}
}
function drupalvb_get_options() {
static $options = array();
Ed Brown
committed
$result = drupalvb_db_query("SELECT varname, value FROM {setting}");
foreach ($result as $var) {
$options[$var->varname] = $var->value;
}
}
return $options;
}
/**
* Get vBulletin configuration.
*
* @return array
* An associative array containing the vBulletin configuration, plus
* additional key:
* - version: The vBulletin version number string, as contained in the first
* PHP comment lines of config.php.
static $config;
if (!isset($config)) {
$config = array();
$config['version'] = NULL;
// @todo Find & include vB's config automatically?
// $files = file_scan_directory('.', '^config.php$', $nomask = array('.', '..', 'CVS', '.svn'));
$config_file = './' . conf_path() . '/config.php';
if (!file_exists($config_file)) {
$config_file = drupal_get_path('module', 'drupalvb') . '/config.php';
}
if (file_exists($config_file)) {
require_once $config_file;
// Additionally parse the vBulletin version out of the php file header, as
// some integration functionality needs to account for API changes in
// later vBulletin versions.
$file = fopen($config_file, 'r');
$max_lines = 10;
while ($max_lines && $line = fgets($file, 30)) {
if (preg_match('@vBulletin\s+([0-9a-zA-Z\.-]+)@', $line, $version)) {
$config['version'] = $version[1];
}
$max_lines--;
}
fclose($file);
}
}
return $config;
}
/**
* Get vB user roles.
*/
function drupalvb_get_roles() {
$result = drupalvb_db_query("SELECT usergroupid, title FROM {usergroup}");
$roles = array();
foreach ($result as $data) {
$roles[$data->usergroupid] = $data->title;
}
if (!$roles) {
$roles[] = t('No user roles could be found.');
}
return $roles;
}
/**
* Get vB language id by given ISO language code.
*/
Daniel Kudwien
committed
function drupalvb_get_languageid($language = NULL) {
if (!isset($vblanguages)) {
$vblanguages = array();
$result = drupalvb_db_query("SELECT languageid, title, languagecode FROM {language}");
foreach ($result as $lang) {
$vblanguages[$lang->languagecode] = $lang->languageid;
}
}
Ed Brown
committed
$options = drupalvb_get_options();
return 1;
//return (!empty($language) && isset($vblanguages[$language]) ? $vblanguages[$language] : $vblanguages[$options['languageid']]);
}
/**
* Get counts of guests and members currently online.
*/
function drupalvb_get_users_online() {
Ed Brown
committed
$vb_options = drupalvb_get_options();
$datecut = time() - $vb_options['cookietimeout'];
$numberregistered = 0;
$result = drupalvb_db_query("SELECT user.username, user.usergroupid, session.userid, session.lastactivity FROM {session} AS session LEFT JOIN {user} AS user ON (user.userid = session.userid) WHERE session.lastactivity > :datecut", array(':datecut' => $datecut));
$userinfos = array();
while ($loggedin = $result->fetchAssoc()) {
$userid = $loggedin['userid'];
$numberguest++;
elseif (empty($userinfos[$userid]) || ($userinfos[$userid]['lastactivity'] < $loggedin['lastactivity'])) {
}
$numberregistered++;
return array('guests' => $numberguest, 'members' => $numberregistered);
}
* Get counts of new or recent posts for the current user.
function drupalvb_get_recent_posts($scope = 'last') {
global $user;
// Queries the vB user database to find a matching set of user data.
$result = drupalvb_db_query("SELECT userid, username, lastvisit FROM {user} WHERE username = :name", array(':name' => drupalvb_htmlspecialchars($user->name)));
// Make sure a user is logged in to get their last visit and appropriate post
// count.
if ($vb_user = $result->fetchAssoc()) {
$datecut = $vb_user['lastvisit'];
$datecut = time() - 86400;
$posts = drupalvb_db_query("SELECT COUNT(postid) FROM {post} WHERE dateline > :datecut", array(':datecut' => $datecut))->fetchField();
}
else {
$posts = 0;
}
}
Daniel Kudwien
committed
function drupalvb_htmlspecialchars($text) {
$text = preg_replace('/&(?!#[0-9]+|shy;)/si', '&', $text);
return str_replace(array('<', '>', '"'), array('<', '>', '"'), $text);
}
/**
* Get vB cookie prefix.
*/
function drupalvb_get_cookieprefix() {
Ed Brown
committed
$vb_config = drupalvb_get_config();
$cookie_prefix = (isset($vb_config['Misc']['cookieprefix']) ? $vb_config['Misc']['cookieprefix'] : 'bb');
// Version 4 began using an underscore following the prefix.
if (version_compare($vb_config['version'], 4, '>=')) {
$cookie_prefix .= '_';
}
return $cookie_prefix;
}