View Single Post
  #70  
Old 10-13-2007, 04:16 AM
amatulic amatulic is offline
 
Join Date: Sep 2007
Posts: 3
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

After much testing and examining vBulletin code, I finally finished my PHP class for performing basic operations on user accounts (create user, modify user, delete user, log on, log off). This has enabled me to integrate the forum into my site. Users who log in to my site are logged in to the forum, users who register on my site automatically get an account on the forum, etc.

Once that was done, I just had to modify all the vBulletin templates that contained a login form, logout link, register link, or user account modification link, and make sure those things use MY code for those functions. Now users can log in either from the forum or from my main site, and user account registration and modification are all handled on my main site, outside of the forum. It all works pretty well, without modifying a single line of the vBulletin source code.

Here is the code for class.forumops.php, with extensive usage comments:
PHP Code:
<?php
//==============================================================
// class ForumOps - intended to be used with vBulletin 3.7.2
// by Alex Matulich, June 2008, Unicorn Research Corporation
//
// Setup:
// ------
//
// 1. First, make sure FORUMPATH is defined properly below.
//
// 2. Next, make sure the function userdata_convert correctly converts
// an array of your own user data to an array of vBulletin user data.
// Minimally, you need to convert your data to an array containing
// the keys 'username', 'password', and 'email'.  If your data array
// already contains these keys, simply have userdata_convert return
// the original array, otherwise translate your array to a vBulletin
// array having those keys.
//
// Usage:
// ------
//
// At the top of your php modules where you need to perform vBulletin
// user operations (creation, deletion, updating, login, and logout),
// put these two lines (where MY_PATH is the path to this file):
//
//     require_once(MY_PATH.'/class.forumops.php');
//     $forum = new ForumOps();
//
// Now get your user data array from $_POST or whatever.  Let's call
// this array $userdata.  Here's what you can do:
//
// CREATE AND REGISTER NEW USER:
//
//    $errmsg = $forum->register_newuser($userdata);
//
// UPDATE EXISTING USER DATA:
//
//    $errmsg = $forum->update_user($userdata);
//
// (In this case, $userdata need contain only the username and anything
// else you wish to update, such as password and/or email address.)
//
// $errmsg contains any error messages separated by <br> codes.
// If no errors occured then NULL is returned.
//
// DELETE USER:
//
//    $forum->delete_user($username); // $username = user name
//
// LOGIN USER TO THE FORUM:
//
//    $forum->login(  // requires array to be passed
//       array('username' => $username, 'password' => $pw);
//
// LOG OFF USER FROM THE FORUM:
//
//    $forum->logout();
//
// WARNING: It is common for you to have TABLE_PREFIX defined for
// your own database.  You must call it something else (for example,
// remove the underscore) or it will conflict with the vBulletin
// definition of the same name.
//===============================================================

//===============================================================
// Change this definition and the userdata_convert() function
// to suit your needs:

define('FORUMPATH''/home/my_website_path/forum'); // path to your forum

function userdata_convert(&$userdata// internal function
{
   
// $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['userid'] );
   if (isset(
$userdata['email']))
      
$vbuser['email'] = $userdata['email'];
   if (isset(
$userdata['password']))
      
$vbuser['password'] = $userdata['password'];

   
// extra stuff, expand as desired
   
if ($userdata['birthdate'])
      
$vbuser['birthday_search'] = date('Y-m-d'$userdata['birthdate']);
   return 
$vbuser;
}
// end of configuration stuff
//===============================================================

define('REGISTERED_USERGROUP'2); // typical default for registered users
define('PERMANENT_COOKIE'false); // false=session cookies (recommended)

define('THIS_SCRIPT'__FILE__);
$cwd getcwd();
chdir(FORUMPATH);
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


//---------------------------------------------------------------------
// 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.
//---------------------------------------------------------------------
function fetch_userinfo_from_username(&$username$option=0$languageid=0)
{
   global 
$vbulletin;
   
$useridq $vbulletin->db->query_first_slave("SELECT userid FROM "
      
TABLE_PREFIX "user WHERE username='{$username}'");
   if (!
$useridq) return $useridq;
   
$userid $useridq['userid'];
   return 
fetch_userinfo($userid$option$languageid);
}


//---------------------------------------------------------------------
// CLASS ForumOps
//---------------------------------------------------------------------
class ForumOps extends vB_DataManager_User {
   var 
$userdm;

   function 
ForumOps() // constructor
   
{
      global 
$vbulletin;
      
$this->userdm =& datamanager_init('User'$vbulletinERRTYPE_ARRAY);
   }


   
//======== USER REGISTRATION / UPDATE / DELETE ========

   
function register_newuser(&$userdata$login true)
   {
      global 
$vbulletin;
      
$vbuser userdata_convert($userdata);
      foreach(
$vbuser as $key => $value)
         
$this->userdm->set($key$value);
      
$this->userdm->set('usergroupid'REGISTERED_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);

      if (
$login$this->login($vbuser);

      
//$this->userdm->errors contains error messages
      
if (empty($this->userdm->errors))
         
$vbulletin->userinfo['userid'] = $this->userdm->save();
      else
         return 
implode('<br>'$this->userdm->errors);
      return 
NULL;
   }


   function 
update_user(&$userdata)
   {
      global 
$vbulletin;
      
$vbuser userdata_convert($userdata);
      if (!(
$existing_user fetch_userinfo_from_username($vbuser['username'])))
         return 
'fetch_userinfo_from_username() failed.';

      
$this->userdm->set_existing($existing_user);
      foreach(
$vbuser as $key => $value)
         
$this->userdm->set($key$value);

      
// reset password cookie in case password changed
      
if (isset($vbuser['password']))
         
vbsetcookie('password',
            
md5($vbulletin->userinfo['password'].COOKIE_SALT),
            
PERMANENT_COOKIEtruetrue);

      if (
count($this->userdm->errors))
         return 
implode('<br>'$this->userdm->errors);
      
$vbulletin->userinfo['userid'] = $this->userdm->save();
      return 
NULL;
   }


   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.

      
global $vbulletin;
      
$db = &$vbulletin->db;
      
$userdata $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
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"subscribeforum WHERE userid={$userid}");
         
// delete subscribed threads
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"subscribethread WHERE userid={$userid}");
         
// delete events
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"event WHERE userid={$userid}");
         
// delete event reminders
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"subscribeevent WHERE userid={$userid}");
         
// delete custom avatars
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"customavatar WHERE userid={$userid}");
         
$customavatars $db->query_read("SELECT userid, avatarrevision FROM "
          
TABLE_PREFIX "user WHERE userid={$userid}");
         while (
$customavatar $db->fetch_array($customavatars)) {
            @
unlink($vbulletin->options['avatarpath'] . "/avatar{$customavatar['userid']}_{$customavatar['avatarrevision']}.gif");
         }
         
// delete custom profile pics
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"customprofilepic WHERE userid={$userid}");
         
$customprofilepics $db->query_read(
            
"SELECT userid, profilepicrevision FROM "
            
TABLE_PREFIX "user WHERE userid={$userid}");
         while (
$customprofilepic $db->fetch_array($customprofilepics)) {
            @
unlink($vbulletin->options['profilepicpath'] . "/profilepic$customprofilepic[userid]_$customprofilepic[profilepicrevision].gif");
         }
         
// delete user forum access
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"access WHERE userid={$userid}");
         
// delete moderator
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"moderator WHERE userid={$userid}");
         
// delete private messages
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"pm WHERE userid={$userid}");
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"pmreceipt WHERE userid={$userid}");
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"session WHERE userid={$userid}");
         
// delete user group join requests
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"usergrouprequest WHERE userid={$userid}");
         
// delete bans
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"userban WHERE userid={$userid}");
         
// delete user notes
         
$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
         
$db->query_write("UPDATE " TABLE_PREFIX
            
"thread SET postuserid = 0, postusername = '"
            
$db->escape_string($username)
            . 
"' WHERE postuserid = $userid");
         
$db->query_write("UPDATE " TABLE_PREFIX
            
"post SET userid = 0, username = '"
            
$db->escape_string($username)
            . 
"' WHERE userid = $userid");

         
// finally, delete the user
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"usertextfield WHERE userid={$userid}");
         
$db->query_write("DELETE FROM " TABLE_PREFIX
            
"userfield WHERE userid={$userid}");
         
$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 ========

   
function login($vbuser)
   {
      global 
$vbulletin;
      
$vbulletin->userinfo fetch_userinfo_from_username($vbuser['username']);

      
// update password expire time to
      // to prevent vBulletin from expiring the password
      
$this->userdm->set_existing($vbulletin->userinfo);
      
$this->userdm->set('passworddate''FROM_UNIXTIME('.TIMENOW.')'false);
      
$this->userdm->save();

      
// set cookies
      
vbsetcookie('userid'$vbulletin->userinfo['userid'],
         
PERMANENT_COOKIEtruetrue);
      
vbsetcookie('password',
         
md5($vbulletin->userinfo['password'].COOKIE_SALT),
         
PERMANENT_COOKIEtruetrue);

      
// create session stuff
      
process_new_login(''1'');
   }


   function 
logout()
   {
      
process_logout(); // unsets all cookies and session data
   
}

// end class ForumOps
chdir($cwd);
?>
As you can see, most of the operations above are pretty simple, except for the user deletion function. Also, to update user account information, see the first post of this thread for options you can use.

The wordwrapping above looks funny, but if you quote this message as if to reply, the wordwrapping will be correct when you copy and paste it.

I hope this helps some people.
-Alex
Reply With Quote
 
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.01427 seconds
  • Memory Usage 1,991KB
  • Queries Executed 11 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD_SHOWPOST
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)bbcode_php
  • (1)footer
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (6)option
  • (1)post_thanks_box
  • (1)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (1)post_thanks_postbit_info
  • (1)postbit
  • (1)postbit_onlinestatus
  • (1)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open 

Phrase Groups Available:
  • global
  • postbit
  • reputationlevel
  • showthread
Included Files:
  • ./showpost.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_postinfo_query
  • fetch_postinfo
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showpost_start
  • bbcode_fetch_tags
  • bbcode_create
  • postbit_factory
  • showpost_post
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • fetch_musername
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • showpost_complete