Login   Register  
PHP Classes
elePHPant
Icontem

File: class.vbulletin-bridge.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Sam Cleaver  >  vBulletin Bridge  >  class.vbulletin-bridge.php  >  Download  
File: class.vbulletin-bridge.php
Role: Class source
Content type: text/plain
Description: Main Class
Class: vBulletin Bridge
Integrate site users with vBulletin member system
Author: By
Last change: Tidied up source into seperate files.
Date: 5 years ago
Size: 26,984 bytes
 

Contents

Class file image Download
<?php
//==============================================================
// class vBulletin-Bridge
// See README, INSTALL for installation/config/usage instructions
// Released under the new BSD license.
// Copyright (c) 2009, Sam Cleaver (Beaver6813) All rights reserved.
//===============================================================

//===============================================================
// Change forum path to the absolute path to your forum, change
// usergroupid's to fit with your forum installation.

define('FORUMPATH', '/absolute/path/to/forum'); // path to your forum

define('REGISTERED_USERGROUP', 2); // typical default for registered users
define('BANNED_USERGROUP', 19); // typical default for banned
define('NOACTIVATION_USERGROUP', 3); // typical default for user awaiting activation
define('PERMANENT_COOKIE', false); // false=session cookies (recommended)

// end of configuration stuff
//===============================================================
define('THIS_SCRIPT', __FILE__);
$cwd = getcwd();
chdir(FORUMPATH);
require_once('./global.php');
require_once('./includes/init.php'); // includes class_core.php
require_once('./includes/class_dm.php'); // for class_dm_user.php
require_once('./includes/class_dm_user.php'); // for user functions
require_once('./includes/functions.php'); // vbsetcookie etc.
require_once('./includes/functions_login.php'); // process login/logout
require_once('./includes/functions_user.php'); // enable us to sort out activation

//---------------------------------------------------------------------
// CLASS vBulletin_Bridge
//---------------------------------------------------------------------
class vBulletin_Bridge extends vB_DataManager_User {
   var $userdm;
   var $vbulletin;
   var $db;
   function vBulletin_Bridge() // constructor
   {
      global $vbulletin;
	  $this->vbulletin = $vbulletin;
	  $this->db = $this->vbulletin->db;
      $this->userdm =& datamanager_init('User', $this->vbulletin, ERRTYPE_ARRAY);
   }
//---------------------------------------------------------------------
// This function duplicates the functionality of fetch_userinfo(),
// using the user name instead of numeric ID as the argument.
// See comments in includes/functions.php for documentation.
//---------------------------------------------------------------------
	private function fetch_userinfo_from_username($username, $option=0, $languageid=0)
	{
	   $result = $this->db->query("SELECT * FROM "
		  . TABLE_PREFIX . "user WHERE username = '".$username."'");
		$useridq = $this->db->fetch_array($result);  
	   if (!$useridq) return $useridq;
	   $userid = $useridq['userid'];
	   return fetch_userinfo($userid, $option, $languageid);
	}
//---------------------------------------------------------------------
// Internal function used for converting userdata to the right format 
// to vBulletin
//---------------------------------------------------------------------
  private function userdata_convert(&$userdata) 
  {
	 // $userdata is our array that contains user data from our own
	 // user database, which we must convert to the vBulletin values.
	 // Minimally, it must contain the username, email and/or password.
  
	 // required fields
	 $vbuser = array( 'username' => $userdata['username'] );
	 if (isset($userdata['email']))
		$vbuser['email'] = $userdata['email'];
	 if (isset($userdata['password']))
		$vbuser['password'] = $userdata['password'];
	  $vbuser['ipaddress'] = $_SERVER['REMOTE_ADDR'];
	 // extra stuff, expand as desired
	 if ($userdata['usergroupid'])
		$vbuser['usergroupid'] = $userdata['usergroupid'];
	 if ($userdata['usertitle'])
		$vbuser['usertitle'] = $userdata['usertitle'];
	 return $vbuser;
  }

   //======== USER REGISTRATION / UPDATE / DELETE ========
//---------------------------------------------------------------------
// Register new user, requires userdata username, password and email,
// details on how to wrap up userdata outlined above. 
// Optional, set $noactivate to true and automatically activate user,
// useful if validation system already in place.
//---------------------------------------------------------------------
public function register_newuser(&$userdata,$noactivate=false)
   {
      $vbuser = $this->userdata_convert($userdata);
      foreach($vbuser as $key => $value)
         $this->userdm->set($key, $value);
      $this->userdm->set('usergroupid', NOACTIVATION_USERGROUP);

      // Bitfields; set to desired defaults.
      // Comment out those you have set as defaults
      // in the vBuleltin admin control panel
      $this->userdm->set_bitfield('options', 'adminemail', 1);
      $this->userdm->set_bitfield('options', 'showsignatures', 1);
      $this->userdm->set_bitfield('options', 'showavatars', 1);
      $this->userdm->set_bitfield('options', 'showimages', 1);
      $this->userdm->set_bitfield('options', 'showemail', 0);

      //$this->userdm->errors contains error messages
      if (empty($this->userdm->errors))
         $this->vbulletin->userinfo['userid'] = $this->userdm->save();
      else
         return implode(" ",$this->userdm->errors);
	//Assign VB Script variables
	  $email = $vbuser['email'];
	  $userid = $this->vbulletin->userinfo['userid'];
	  $username = $vbuser['username'];
	  $vbsiteurl = SITE_URL;
	//Build activation id (uses vb's built-in function)
		$activateid = build_user_activation_id($userid, 2, 0);
	//If $noactivate is set to true then we skip sending activation email and just activate user
	if($noactivate)
		{
		$activatestatus = $this->activate_user($userid,$activateid);
		//It will only be true if an error has occured, in which case return it
		if($activatestatus)
			return $activatestatus;
		}
	else
		{
		//Parse variables for email messsage, also subsitutes in activateid, userid, username and email
			eval(fetch_email_phrases('activateaccount'));
		//Send activation email
			vbmail($email, $subject, $message, true);	
		}

	//Reset userid to 0 as to not confuse script
		$this->vbulletin->userinfo['userid'] = 0;
      return false;
   }
//---------------------------------------------------------------------
// Activates user when provided with userid ($u) and activation key ($i)
// Unlike most functions it returns FALSE if it activates successfully
// and returns a string with the error message if it is unsuccessful.
//---------------------------------------------------------------------
public function activate_user($u,$i)
   	{
	//Retrieve userinfo from userid supplied
	$userinfo = verify_id('user', $u, 1, 1);	
	//If they are awaiting activation
	if ($userinfo['usergroupid'] == NOACTIVATION_USERGROUP)
	{
		// check valid activation id
		$user = $this->db->query_first("
			SELECT activationid, usergroupid, emailchange
			FROM ".TABLE_PREFIX."useractivation
			WHERE activationid = '" . $this->db->escape_string($i) . "'
				AND userid = $userinfo[userid]
				AND type = 0
		");
		if (!$user OR $i != $user['activationid'])
		{
		// give link to resend activation email
		return "Invalid activation ID or user ID. Click <a href='register.php?do=requestemail&u=$u'>here</a> to request a new activation email.";
		}
		// delete activationid
		$this->db->query_write("DELETE FROM ".TABLE_PREFIX."useractivation WHERE userid=$userinfo[userid] AND type=0");
		//If we dont have a usergroup for the user, assign to the whatever has been set in config as registered usergroup
		if (empty($user['usergroupid']))
		{
			$user['usergroupid'] = REGISTERED_USERGROUP; // sanity check
		}
		//Get the username for user
		$getusername = $this->db->query_first("
			SELECT username
			FROM ".TABLE_PREFIX."user
			WHERE userid = '" . $this->db->escape_string($u) . "'");
		//Wrap up new userdata
		$userdata = array('username'=>$getusername['username'],'usergroupid'=>REGISTERED_USERGROUP,'usertitle'=>'Junior Member');
		//Update user with new usergroup/title, if unsuccessful, return the error message
		if($updateug = $this->update_user($userdata))
			return $updateug;
		//If update was successful send welcome email (note we use a custom phrase for the "main" site)
		if ($this->vbulletin->options['welcomemail'])
			{
				eval(fetch_email_phrases('welcomemail'));
				vbmail($userinfo['email'], $subject, $message);
			}
		//Reset userid so we dont confuse the script
		$this->vbulletin->userinfo['userid'] = 0;	
		//Return false which indicates success
		return false;
		
	}
	else
		return "This account has already been activated. Click <a href='login.php'>here</a> to login.";
		
	}
//---------------------------------------------------------------------
// Used before a user is activated, link given in initial activation
// email, removes activation key and deletes user. Only used for un-
// activated users, requires userid ($u) and activation key ($i)
//---------------------------------------------------------------------
   public function deactivate_user($u,$i)
   	{
	//Retrieve userinfo from userid supplied
	$userinfo = verify_id('user', $u, 1, 1);	
	//If they are awaiting activation
	if ($userinfo['usergroupid'] == NOACTIVATION_USERGROUP)
	{
		// check valid activation id
		$user = $this->db->query_first("
			SELECT activationid, usergroupid, emailchange
			FROM ".TABLE_PREFIX."useractivation
			WHERE activationid = '" . $this->db->escape_string($i) . "'
				AND userid = $userinfo[userid]
				AND type = 0
		");
		if (!$user OR $i != $user['activationid'])
		{
		// give link to resend activation email
		return "Invalid activation ID or user ID. Click <a href='register.php?do=requestemail&u=$u'>here</a> to request a new activation email.";
		}
		// delete activationid
		$this->db->query_write("DELETE FROM ".TABLE_PREFIX."useractivation WHERE userid=$userinfo[userid] AND type=0");
		//If we dont have a usergroup for the user, assign to whatever has been set in config as registered usergroup
		if (empty($user['usergroupid']))
		{
			$user['usergroupid'] = REGISTERED_USERGROUP; // sanity check
		}
		//Get the username for user
		$getusername = $this->db->query_first("
			SELECT username
			FROM ".TABLE_PREFIX."user
			WHERE userid = '" . $this->db->escape_string($u) . "'");
		//Remove totally!
		$this->delete_user($getusername['username']);
		//Reset userid so we dont confuse the script
		$this->vbulletin->userinfo['userid'] = 0;	
		//Return false which means success!
		return false;
		
	}
	else
		return "This account has already been activated. Click <a href='login.php'>here</a> to login.";
		
	}
//---------------------------------------------------------------------
// Used to request a new activation email incase they didnt recieve the
// first one. Only requires the email address the original one was sent
// to ($email).
//---------------------------------------------------------------------
   public function requestact_user($email)
   	{
	//Get user info from email given/check they actually exist
	$users = $this->db->query_read_slave("
		SELECT user.userid, user.usergroupid, username, email, activationid, languageid
		FROM ".TABLE_PREFIX."user AS user
		LEFT JOIN useractivation AS useractivation ON(user.userid = useractivation.userid AND type = 0)
		WHERE email = '" . $this->db->escape_string($email) . "'"
	);
	//If they exist then carry on
	if ($this->db->num_rows($users))
	{
		//Loop through everyone with the same email address
		while ($user = $this->db->fetch_array($users))
		{
			//Only work on those who are still not activated
			if ($user['usergroupid'] == NOACTIVATION_USERGROUP)
			{ 
				//If they for some crazy reason do not have an activation ID then...
				if (empty($user['activationid']))
				{ 
					//Create a new activation ID for the user
					$user['activationid'] = build_user_activation_id($user['userid'], 2, 0);
				}
				else
				{
					//If they already have an activation ID we'll update the current entry with a new ID
					$user['activationid'] = fetch_random_string(40);
					$this->db->query_write("
						UPDATE ".TABLE_PREFIX."useractivation SET
							dateline = " . TIMENOW . ",
							activationid = '$user[activationid]'
						WHERE userid = $user[userid]
							AND type = 0
					");
				}
				//Set some required VB variables (for the email)
				$userid = $user['userid'];
				$username = $user['username'];
				$activateid = $user['activationid'];
				//Send out activation email, note the custom vbulletin phrase for the "main" site!
				eval(fetch_email_phrases('activateaccount', $user['languageid']));
				//Actually send the email
				vbmail($user['email'], $subject, $message, true);
			}
		}
		//Return as a success
		return false;
	}
	else
	{
		return "No account with that email address exists, please try again.";
	}
	}
//---------------------------------------------------------------------
// Used to request a new request a new password incase they forgot their
// old one! Only requires user accounts email ($email). Returns false on success
//---------------------------------------------------------------------
   public function request_password($email)
   	{
	//Get the userid from their email address
	$getuserid = $this->db->query_first("
			SELECT userid
			FROM ".TABLE_PREFIX."user
			WHERE email = '" . $this->db->escape_string($email) . "'");
	//Gets list of users with the email address
	$users = $this->db->query_read_slave("
		SELECT userid, username, email, languageid
		FROM " . TABLE_PREFIX . "user
		WHERE email = '" . $this->db->escape_string($email) . "'
	");
	if ($this->db->num_rows($users))
	{
		//Loops through users
		while ($user = $this->db->fetch_array($users))
		{
			//If the userid's do not match up with whats in the database
			if ($getuserid['userid'] AND $getuserid['userid'] != $user['userid'])
			{
				//Exit the loop
				continue;
			}
			//Set vb username
			$user['username'] = unhtmlspecialchars($user['username']);
			//Generate new activation id
			$user['activationid'] = build_user_activation_id($user['userid'], 2, 1);
			//Use custom phrase and send out lost password email
			eval(fetch_email_phrases('lostpw', $user['languageid']));
			vbmail($user['email'], $subject, $message, true);
		}
		//Return as a success
		return false;
	}
	else
	{
		return "No account with that email address exists, please try again.";
	}
		
	}
//---------------------------------------------------------------------
// Accessed only from change_password(), you shouldn't need this.
// Requires userid ($u) and activation key ($i), returns false on success
//---------------------------------------------------------------------
  private function check_password_request($u,$i)
   	{
	//Retrieve userinfo from userid supplied
	$userinfo = verify_id('user', $u, 1, 1);	
	//Get user with matching userid and with a request for new password
	$user = $this->db->query_first("
		SELECT activationid, dateline
		FROM " . TABLE_PREFIX . "useractivation
		WHERE type = 1
			AND userid = $u
	");
	//Check if doesnt exist
	if (!$user)
		{
		return "New password request for this user not placed.";
		}
	//If its been longer than 24 hours than the password request was placed
	if ($user['dateline'] < (TIMENOW - 24 * 60 * 60))
		{  // is it older than 24 hours?
		return "Lost password key expired. It has been longer than 24 hours since you requested it. You can request a new one <a href='login.php?do=lostpw'>here</a>.";
		}
	//If activation ID doesnt match that of the user
	if ($user['activationid'] != $i)
	{ //wrong act id
			return "Invalid lost password key. Click <a href='login.php?do=lostpw'>here</a> to request a new one.";
	}
	//If we haven't already returned it must be fine, return false!
	return false;
	}
//---------------------------------------------------------------------
// Public function to change the password.
// Requires userid ($u) and activation key ($i), returns false on success
// Optional, defaults to logging in user after password change, can be 
// changed to false.
//---------------------------------------------------------------------
   public function change_password($u,$i,$password,$login=true)
   	{
	//Check if password request is correct
	if($check_codes = $this->check_password_request($u,$i))
		return $check_codes;
		
	// delete old activation id
	$this->db->query_write("DELETE FROM " . TABLE_PREFIX . "useractivation WHERE userid = $u AND type = 1");
	//Get the username from the userid
	$getusername = $this->db->query_first("
			SELECT username
			FROM ".TABLE_PREFIX."user
			WHERE userid = '" . $this->db->escape_string($u) . "'");
	//Create array for password change
	$build_update = array("username"=>$getusername['username'],"password"=>$password);
	//Commit password change
	$user_changed = $this->update_user($build_update);
	//If login is set to true then log the user in
	if($login&&!$user_changed)
		$this->login($buildupdate);
	//If all is correct $user_changed should be false and so should return false
	return $user_changed;
		
	}
//---------------------------------------------------------------------
// Update user details. Very important function requires $userdata,
// configuration details for this can be found above.
//---------------------------------------------------------------------
   public function update_user(&$userdata)
   {
	  //Validate userdata by passing through our userdata_convert function
      $vbuser = $this->userdata_convert($userdata);
	  //Check for userinfo from the username provided
      	if (!($existing_user = $this->fetch_userinfo_from_username($vbuser['username'])))
         	return 'Username does not exist.';
	  //Set existing user data
      $this->userdm->set_existing($existing_user);
	  //Loop through new user data and set it
      foreach($vbuser as $key => $value)
         $this->userdm->set($key, $value);
      // reset password cookie in case password changed
      if (isset($vbuser['password']))
         vbsetcookie('password',
            md5($this->vbulletin->userinfo['password'].COOKIE_SALT),
            PERMANENT_COOKIE, true, true);
	  //If there are any errors return them
      if (count($this->userdm->errors))
         return $this->userdm->errors; 
	  //If there are no errors then SAVE the set data and return false.
      $this->vbulletin->userinfo['userid'] = $this->userdm->save();
      return false;
   }
//---------------------------------------------------------------------
// Completely deletes user, experimental and is not reccomended for normal
// use due to the irregularities it can create with post counts. We only 
// use it delete non-activated users.
// Requires only the username ($username)
//---------------------------------------------------------------------
   public function delete_user(&$username)
   {
   // The vBulletin documentation suggests using userdm->delete()
   // to delete a user, but upon examining the code, this doesn't
   // delete everything associated with the user.  The following
   // is adapted from admincp/user.php instead.
   // NOTE: THIS MAY REQUIRE MAINTENANCE WITH NEW VBULLETIN UPDATES.

      $userdata = $this->db->query_first_slave("SELECT userid FROM "
         . TABLE_PREFIX . "user WHERE username='{$username}'");
      $userid = $userdata['userid'];
      if ($userid) {

      // from admincp/user.php 'do prune users (step 1)'

         // delete subscribed forums
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "subscribeforum WHERE userid={$userid}");
         // delete subscribed threads
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "subscribethread WHERE userid={$userid}");
         // delete events
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "event WHERE userid={$userid}");
         // delete event reminders
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "subscribeevent WHERE userid={$userid}");
         // delete custom avatars
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "customavatar WHERE userid={$userid}");
         $customavatars = $this->db->query_read("SELECT userid, avatarrevision FROM "
          . TABLE_PREFIX . "user WHERE userid={$userid}");
         while ($customavatar = $this->db->fetch_array($customavatars)) {
            @unlink($this->vbulletin->options['avatarpath'] . "/avatar{$customavatar['userid']}_{$customavatar['avatarrevision']}.gif");
         }
         // delete custom profile pics
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "customprofilepic WHERE userid={$userid}");
         $customprofilepics = $this->db->query_read(
            "SELECT userid, profilepicrevision FROM "
            . TABLE_PREFIX . "user WHERE userid={$userid}");
         while ($customprofilepic = $this->db->fetch_array($customprofilepics)) {
            @unlink($this->vbulletin->options['profilepicpath'] . "/profilepic$customprofilepic[userid]_$customprofilepic[profilepicrevision].gif");
         }
         // delete user forum access
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "access WHERE userid={$userid}");
         // delete moderator
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "moderator WHERE userid={$userid}");
         // delete private messages
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "pm WHERE userid={$userid}");
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "pmreceipt WHERE userid={$userid}");
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "session WHERE userid={$userid}");
         // delete user group join requests
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "usergrouprequest WHERE userid={$userid}");
         // delete bans
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "userban WHERE userid={$userid}");
         // delete user notes
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "usernote WHERE userid={$userid}");

      // from admincp/users.php 'do prune users (step 2)'

         // update deleted user's posts with userid=0
         $this->db->query_write("UPDATE " . TABLE_PREFIX
            . "thread SET postuserid = 0, postusername = '"
            . $this->db->escape_string($username)
            . "' WHERE postuserid = $userid");
         $this->db->query_write("UPDATE " . TABLE_PREFIX
            . "post SET userid = 0, username = '"
            . $this->db->escape_string($username)
            . "' WHERE userid = $userid");

         // finally, delete the user
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "usertextfield WHERE userid={$userid}");
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "userfield WHERE userid={$userid}");
         $this->db->query_write("DELETE FROM " . TABLE_PREFIX
            . "user WHERE userid={$userid}");
      }
   /*
      the following is suggested in the documentation but doesn't work:

      $existing_user = fetch_userinfo_from_username($username);
      $this->userdm->set_existing($existing_user);
      return $this->userdm->delete();
   */
   }


   // ======== USER LOGIN / LOGOUT ========
//---------------------------------------------------------------------
// Main login function, requires userdata formatted correctly. Can also
// filter user groups, $acceptgroups should be an array passed as 
// array(1,2,3,45) etc, this is useful for creating admin only pages etc
// if not set then all activated members will be allowed in.
//---------------------------------------------------------------------
   public function login($vbuser,$acceptgroups=false)
   {
	  //Get user info from username passed
      $this->vbulletin->userinfo = $this->fetch_userinfo_from_username($vbuser['username']);
	  //Verify login via VB
	  if(!verify_authentication($vbuser['username'], $vbuser['password'], '', '', 1, true))
	  	{
		$this->vbulletin->userinfo['userid'] = 0;
	  	return "Invalid Username or Password.";
		}
	//Check that user is not awaiting activation
	if($this->vbulletin->userinfo['usergroupid']==NOACTIVATION_USERGROUP)
		{
		$this->vbulletin->userinfo['userid'] = 0;
	  	return "Un-Activated Account. To activate please request a new activation email <a href='register.php?do=requestemail&username={$vbuser['username']}'>here</a>.";
		}
	//Check user does not belong to the "banned" user group - TODO: Use VB variables incase usergroupid is different
	if($this->vbulletin->userinfo['usergroupid']==BANNED_USERGROUP)
		{
		$this->vbulletin->userinfo['userid'] = 0;
	  	return "You're Barred! If you think there has been a mistake or wish to appeal please visit the contact page <a href='contact.php'>here</a>.";
		}
	//If acceptgroups is set then check that user is part of the usergroups specified
	if($acceptgroups)
		{
		//Check main usergroup as well as additional usergroups
		$getadditional = explode(',',$this->vbulletin->userinfo['membergroupids']);
		//Loop through specified usergroups
		foreach($acceptgroups as $value)
			{
			//If user is part of the usergroup then allowlogin
			if($value == $this->vbulletin->userinfo['usergroupid'])
				$allowlogin = true;
			//Check additional usergroups
			foreach($getadditional as $additionalvalue)
				{
				//If user is part of the usergroup then allowlogin
				if($value == $additionalvalue)
					$allowlogin = true;	
				}
			}
		//If user is not part of any specified usergroups then return error.
		if(!$allowlogin)
			{
			$this->vbulletin->userinfo['userid'] = 0;
	  		return "This is a restricted area. Please contact the site administrator for further details.";	
			}
		}
		//Unstrike the user (resets vbulletin brute-force protection)
		exec_unstrike_user($vbuser['username']);
	  //Create vbulletin cookies for user
      process_new_login('', 1, '');
	  //Saves cookies & session variables for user
	  $this->vbulletin->session->save();
	  //Return false for success!
	  return false;
   }
//---------------------------------------------------------------------
// Very simple function used to LOGOUT, requires no variables, logs out
// currently logged in user.
//---------------------------------------------------------------------
   public function logout()
   {
	  // unsets all cookies and session data
      process_logout(); 
   }

} // end class vBulletin_Bridge
chdir($cwd);
?>