/[drupal]/contributions/modules/drupalvb/drupalvb.inc.php
ViewVC logotype

Contents of /contributions/modules/drupalvb/drupalvb.inc.php

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.34 - (show annotations) (download) (as text)
Mon Mar 9 04:46:21 2009 UTC (8 months, 2 weeks ago) by sun
Branch: MAIN
CVS Tags: HEAD
Changes since 1.33: +16 -9 lines
File MIME type: text/x-php
#336632 by jcfiala, sun: Fixed vB cookies not removed on logout.
1 <?php
2 // $Id: drupalvb.inc.php,v 1.33 2009/02/01 02:00:25 sun Exp $
3
4 /**
5 * @file
6 * Drupal vB CRUD functions.
7 */
8
9 /**
10 * Set the necessary cookies for the user to be logged into the forum.
11 *
12 * Frontend cookie names:
13 * - lastvisit, lastactivity, sessionhash
14 * Backend cookie names:
15 * - cpsession, userid, password
16 *
17 * However, in all cases the cookiedomain is NOT prefixed with a dot unless
18 * cookie domain has not been manually altered to either a suggested value or
19 * custom value in vB's settings.
20 */
21 function drupalvb_set_login_cookies($userid) {
22 // Load required vB user data.
23 $vbuser = db_fetch_array(drupalvb_db_query("SELECT userid, password, salt FROM {user} WHERE userid = %d", $userid));
24 if (!$vbuser) {
25 return FALSE;
26 }
27
28 $vb_config = drupalvb_get('config');
29 $vb_options = drupalvb_get('options');
30
31 $cookie_prefix = (isset($vb_config['Misc']['cookieprefix']) ? $vb_config['Misc']['cookieprefix'] : 'bb');
32 $cookie_path = $vb_options['cookiepath'];
33 $now = time();
34 $expire = $now + (@ini_get('session.cookie_lifetime') ? ini_get('session.cookie_lifetime') : 60 * 60 * 24 * 365);
35
36 $vb_cookie_domain = (!empty($vb_options['cookiedomain']) ? $vb_options['cookiedomain'] : $GLOBALS['cookie_domain']);
37 // Per RFC 2109, cookie domains must contain at least one dot other than the
38 // first. For hosts such as 'localhost' or IP Addresses we don't set a cookie domain.
39 // @see conf_init()
40 if (!(count(explode('.', $vb_cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $vb_cookie_domain)))) {
41 $vb_cookie_domain = '';
42 }
43
44 // Clear out old session (if available).
45 if (!empty($_COOKIE[$cookie_prefix .'sessionhash'])) {
46 drupalvb_db_query("DELETE FROM {session} WHERE sessionhash = '%s'", $_COOKIE[$cookie_prefix .'sessionhash']);
47 }
48
49 // Setup user session.
50 $ip = implode('.', array_slice(explode('.', drupalvb_get_ip()), 0, 4 - $vb_options['ipcheck']));
51 $idhash = md5($_SERVER['HTTP_USER_AGENT'] . $ip);
52 $sessionhash = md5($now . request_uri() . $idhash . $_SERVER['REMOTE_ADDR'] . user_password(6));
53
54 drupalvb_db_query("REPLACE INTO {session} (sessionhash, userid, host, idhash, lastactivity, location, useragent, loggedin) VALUES ('%s', %d, '%s', '%s', %d, '%s', '%s', %d)", $sessionhash, $vbuser['userid'], substr($_SERVER['REMOTE_ADDR'], 0, 15), $idhash, $now, '/forum/', $_SERVER['HTTP_USER_AGENT'], 2);
55
56 // Setup cookies.
57 setcookie($cookie_prefix .'sessionhash', $sessionhash, $expire, $cookie_path, $vb_cookie_domain);
58 setcookie($cookie_prefix .'lastvisit', $now, $expire, $cookie_path, $vb_cookie_domain);
59 setcookie($cookie_prefix .'lastactivity', $now, $expire, $cookie_path, $vb_cookie_domain);
60 setcookie($cookie_prefix .'userid', $vbuser['userid'], $expire, $cookie_path, $vb_cookie_domain);
61 setcookie($cookie_prefix .'password', md5($vbuser['password'] . variable_get('drupalvb_license', '')), $expire, $cookie_path, $vb_cookie_domain);
62 return TRUE;
63 }
64
65 /**
66 * Clear all vB cookies for the current user.
67 *
68 * @see drupalvb_logout(), drupalvb_user_logout()
69 */
70 function drupalvb_clear_cookies($userid = NULL) {
71 $vb_config = drupalvb_get('config');
72 $vb_options = drupalvb_get('options');
73
74 $cookie_prefix = (isset($vb_config['Misc']['cookieprefix']) ? $vb_config['Misc']['cookieprefix'] : 'bb');
75 $cookie_path = $vb_options['cookiepath'];
76 $expire = time() - 86400;
77
78 $vb_cookie_domain = (!empty($vb_options['cookiedomain']) ? $vb_options['cookiedomain'] : $GLOBALS['cookie_domain']);
79 // Per RFC 2109, cookie domains must contain at least one dot other than the
80 // first. For hosts such as 'localhost' or IP Addresses we don't set a cookie domain.
81 // @see conf_init()
82 if (!(count(explode('.', $vb_cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $vb_cookie_domain)))) {
83 $vb_cookie_domain = '';
84 }
85
86 if (!empty($userid)) {
87 drupalvb_db_query("DELETE FROM {session} WHERE userid = %d", $userid);
88 drupalvb_db_query("UPDATE {user} SET lastvisit = %d WHERE userid = %d", time(), $userid);
89 }
90
91 setcookie($cookie_prefix .'sessionhash', '', $expire, $cookie_path, $vb_cookie_domain);
92 setcookie($cookie_prefix .'lastvisit', '', $expire, $cookie_path, $vb_cookie_domain);
93 setcookie($cookie_prefix .'lastactivity', '', $expire, $cookie_path, $vb_cookie_domain);
94 setcookie($cookie_prefix .'userid', '', $expire, $cookie_path, $vb_cookie_domain);
95 setcookie($cookie_prefix .'password', '', $expire, $cookie_path, $vb_cookie_domain);
96 }
97
98 /**
99 * Determines the IP address of current user.
100 */
101 function drupalvb_get_ip() {
102 $ip = $_SERVER['REMOTE_ADDR'];
103
104 if (isset($_SERVER['HTTP_CLIENT_IP'])) {
105 $ip = $_SERVER['HTTP_CLIENT_IP'];
106 }
107 else if (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)) {
108 // Make sure we don't pick up an internal IP defined by RFC1918.
109 foreach ($matches[0] as $match) {
110 if (!preg_match("#^(10|172\.16|192\.168)\.#", $match)) {
111 $ip = $match;
112 break;
113 }
114 }
115 }
116 else if (isset($_SERVER['HTTP_FROM'])) {
117 $ip = $_SERVER['HTTP_FROM'];
118 }
119 return $ip;
120 }
121
122 /**
123 * Create a user in vBulletin.
124 *
125 * @param object $account
126 * A Drupal user account.
127 * @param array $edit
128 * Form values provided by hook_user().
129 */
130 function drupalvb_create_user($account, $edit) {
131 // Ensure we are not duplicating a user.
132 if (db_result(drupalvb_db_query("SELECT COUNT(userid) FROM {user} WHERE LOWER(username) = LOWER('%s')", drupalvb_htmlspecialchars($edit['name']))) > 0) {
133 return FALSE;
134 }
135
136 $salt = '';
137 for ($i = 0; $i < 3; $i++) {
138 $salt .= chr(rand(32, 126));
139 }
140 // Note: Password is already hashed during user export.
141 if (isset($edit['md5pass'])) {
142 $passhash = md5($edit['md5pass'] . $salt);
143 }
144 else {
145 $passhash = md5(md5($edit['pass']) . $salt);
146 }
147
148 $passdate = date('Y-m-d', $account->created);
149 $joindate = $account->created;
150
151 // Attempt to grab the user title from the database.
152 $result = drupalvb_db_query("SELECT title FROM {usertitle} WHERE minposts = 0");
153 if ($resarray = db_fetch_array($result)) {
154 $usertitle = $resarray['title'];
155 }
156 else {
157 $usertitle = 'Junior Member';
158 }
159
160 // Divide timezone by 3600, since vBulletin stores hours.
161 $timezone = variable_get('date_default_timezone', 0);
162 $timezone = ($timezone != 0 ? $timezone / 3600 : 0);
163
164 // Default new user options: I got these by setting up a new user how I
165 // wanted and looking in the database to see what options were set for him.
166 $options = variable_get('drupalvb_default_options', '3415');
167
168 // Default usergroup id.
169 $usergroupid = variable_get('drupalvb_default_usergroup', '2');
170
171 // Set up the insertion query.
172 $result = drupalvb_db_query("INSERT INTO {user} (username, usergroupid, password, passworddate, usertitle, email, salt, showvbcode, languageid, timezoneoffset, posts, joindate, lastvisit, lastactivity, options) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', 1, %d, '%s', 0, '%s', '%s', '%s', '%s')", drupalvb_htmlspecialchars($edit['name']), $usergroupid, $passhash, $passdate, $usertitle, $edit['mail'], $salt, drupalvb_get('languageid'), $timezone, $joindate, time(), time(), $options);
173
174 $userid = drupalvb_db_last_insert_id('user', 'userid');
175
176 drupalvb_db_query("INSERT INTO {userfield} (userid) VALUES (%d)", $userid);
177 drupalvb_db_query("INSERT INTO {usertextfield} (userid) VALUES (%d)", $userid);
178
179 // Insert new user into mapping table.
180 drupalvb_set_mapping($account->uid, $userid);
181
182 // Return userid of newly created account.
183 return $userid;
184 }
185
186 /**
187 * Update a user in vBulletin.
188 */
189 function drupalvb_update_user($account, $edit) {
190 $fields = $values = array();
191
192 foreach ($edit as $field => $value) {
193 if (empty($value)) {
194 continue;
195 }
196 switch ($field) {
197 case 'name':
198 $fields[] = "username = '%s'";
199 $values[] = drupalvb_htmlspecialchars($value);
200 break;
201
202 case 'pass':
203 $fields[] = "password = '%s'";
204 // Note: Password is already hashed during user export.
205 if (isset($edit['md5pass'])) {
206 $values[] = md5($edit['md5pass'] . $edit['salt']);
207 }
208 else {
209 $values[] = md5(md5($value) . $edit['salt']);
210 }
211 $fields[] = "salt = '%s'";
212 $values[] = $edit['salt'];
213 $fields[] = "passworddate = '%s'";
214 $values[] = date('Y-m-d', time());
215 break;
216
217 case 'mail':
218 $fields[] = "email = '%s'";
219 $values[] = $value;
220 break;
221
222 case 'language':
223 $fields[] = "languageid = %d";
224 $values[] = drupalvb_get('languageid', $value);
225 break;
226 }
227 }
228 $fields[] = 'lastactivity = %d';
229 $values[] = time();
230
231 // Use previous case insensitive username to update conflicting names.
232 $values[] = drupalvb_htmlspecialchars($account->name);
233 drupalvb_db_query("UPDATE {user} SET ". implode(', ', $fields) ." WHERE LOWER(username) = LOWER('%s')", $values);
234
235 // Ensure this user exists in the mapping table.
236 // When integrating an existing installation, the mapping may not yet exist.
237 $userid = db_result(drupalvb_db_query("SELECT userid FROM {user} WHERE username = '%s'", drupalvb_htmlspecialchars($account->name)));
238 drupalvb_set_mapping($account->uid, $userid);
239 }
240
241 /**
242 * Ensure that a mapping between two existing user accounts exists.
243 *
244 * @param $uid
245 * A Drupal user id.
246 * @param $userid
247 * A vBulletin user id.
248 */
249 function drupalvb_set_mapping($uid, $userid) {
250 db_query("INSERT IGNORE INTO {drupalvb_users} (uid, userid) VALUES (%d, %d)", $uid, $userid);
251 }
252
253 /**
254 * Export all drupal users to vBulletin.
255 */
256 function drupalvb_export_drupal_users() {
257 module_load_include('inc', 'drupalvb');
258
259 $result = db_query("SELECT * FROM {users} ORDER BY uid");
260 while ($user = db_fetch_object($result)) {
261 if ($user->uid == 0) {
262 continue;
263 }
264 // Let create/update functions know that passwords are hashed already.
265 $user->md5pass = $user->pass;
266 if (!drupalvb_create_user($user, (array)$user)) {
267 // Username already exists, update email and password only.
268 // Case insensitive username is required to detect collisions.
269 $vbuser = db_fetch_array(drupalvb_db_query("SELECT salt FROM {user} WHERE LOWER(username) = LOWER('%s')", drupalvb_htmlspecialchars($user->name)));
270 drupalvb_update_user($user, array_merge((array)$user, $vbuser));
271 }
272 }
273 }
274
275 /**
276 * Get vBulletin configuration options.
277 */
278 function drupalvb_get_options() {
279 static $options = array();
280
281 if (empty($options)) {
282 $result = db_query("SELECT varname, value FROM {setting}");
283 while ($var = db_fetch_array($result)) {
284 $options[$var['varname']] = $var['value'];
285 }
286 }
287 return $options;
288 }
289
290 /**
291 * Get vBulletin configuration.
292 */
293 function drupalvb_get_config() {
294 static $config = array();
295
296 // @todo Find & include vB's config automatically?
297 // $files = file_scan_directory('.', '^config.php$', $nomask = array('.', '..', 'CVS', '.svn'));
298 $config_file = drupal_get_path('module', 'drupalvb') .'/config.php';
299 if (empty($config) && file_exists($config_file)) {
300 require_once $config_file;
301 }
302 return $config;
303 }
304
305 /**
306 * Get vB user roles.
307 */
308 function drupalvb_get_roles() {
309 $result = drupalvb_db_query("SELECT usergroupid, title FROM {usergroup}");
310
311 $roles = array();
312 while ($data = db_fetch_object($result)) {
313 $roles[$data->usergroupid] = $data->title;
314 }
315 if (!$roles) {
316 $roles[] = t('No user roles could be found.');
317 }
318 return $roles;
319 }
320
321 /**
322 * Get vB language id by given ISO language code.
323 */
324 function drupalvb_get_languageid($language = NULL) {
325 static $vblanguages;
326
327 if (!isset($vblanguages)) {
328 $vblanguages = array();
329 $result = drupalvb_db_query("SELECT languageid, title, languagecode FROM {language}");
330 while ($lang = db_fetch_array($result)) {
331 $vblanguages[$lang['languagecode']] = $lang['languageid'];
332 }
333 }
334 $options = drupalvb_get('options');
335 return (!empty($language) && isset($vblanguages[$language]) ? $vblanguages[$language] : $vblanguages[$options['languageid']]);
336 }
337
338 /**
339 * Get counts of guests and members currently online.
340 */
341 function drupalvb_get_users_online() {
342 $vb_options = drupalvb_get('options');
343
344 $datecut = time() - $vb_options['cookietimeout'];
345 $numbervisible = 0;
346 $numberregistered = 0;
347 $numberguest = 0;
348
349 $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 > %d", $datecut);
350
351 $userinfos = array();
352
353 while ($loggedin = db_fetch_array($result)) {
354 $userid = $loggedin['userid'];
355 if (!$userid) {
356 $numberguest++;
357 }
358 else if (empty($userinfos[$userid]) || ($userinfos[$userid]['lastactivity'] < $loggedin['lastactivity'])) {
359 $userinfos[$userid] = $loggedin;
360 }
361 }
362 foreach ($userinfos as $userid => $loggedin) {
363 $numberregistered++;
364 }
365 return array('guests' => $numberguest, 'members' => $numberregistered);
366 }
367
368 /**
369 * Get counts of new or recent posts for the current user.
370 */
371 function drupalvb_get_recent_posts($scope = 'last') {
372 global $user;
373
374 // Queries the vB user database to find a matching set of user data.
375 $result = drupalvb_db_query("SELECT userid, username, lastvisit FROM {user} WHERE username = '%s'", drupalvb_htmlspecialchars($user->name));
376
377 // Make sure a user is logged in to get their last visit and appropriate post
378 // count.
379 if ($vb_user = db_fetch_array($result)) {
380 if ($scope == 'last') {
381 $datecut = $vb_user['lastvisit'];
382 }
383 else if ($scope == 'daily') {
384 $datecut = time() - 86400;
385 }
386 $posts = db_result(drupalvb_db_query("SELECT COUNT(postid) FROM {post} WHERE dateline > %d", $datecut));
387 }
388 else {
389 $posts = 0;
390 }
391 return $posts;
392 }
393
394 function drupalvb_htmlspecialchars($text) {
395 $text = preg_replace('/&(?!#[0-9]+|shy;)/si', '&amp;', $text);
396 return str_replace(array('<', '>', '"'), array('&lt;', '&gt;', '&quot;'), $text);
397 }
398

  ViewVC Help
Powered by ViewVC 1.1.2