1230 } |
1251 } |
1231 $keyhash = md5($key); |
1252 $keyhash = md5($key); |
1232 $salt = $db->escape($keydata[3]); |
1253 $salt = $db->escape($keydata[3]); |
1233 // using a normal call to $db->sql_query to avoid failing on errors here |
1254 // using a normal call to $db->sql_query to avoid failing on errors here |
1234 $query = $db->sql_query('SELECT u.user_id AS uid,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,' . "\n" |
1255 $query = $db->sql_query('SELECT u.user_id AS uid,u.username,u.password,u.email,u.real_name,u.user_level,u.theme,u.style,u.signature,' . "\n" |
1235 . ' u.reg_time,u.account_active,u.activation_key,u.user_lang,k.source_ip,k.time,k.auth_level,COUNT(p.message_id) AS num_pms,' . "\n" |
1256 . ' u.reg_time,u.account_active,u.activation_key,u.user_lang,u.user_title,k.source_ip,k.time,k.auth_level,COUNT(p.message_id) AS num_pms,' . "\n" |
1236 . ' u.user_timezone, x.* FROM '.table_prefix.'session_keys AS k' . "\n" |
1257 . ' u.user_timezone, x.* FROM '.table_prefix.'session_keys AS k' . "\n" |
1237 . ' LEFT JOIN '.table_prefix.'users AS u' . "\n" |
1258 . ' LEFT JOIN '.table_prefix.'users AS u' . "\n" |
1238 . ' ON ( u.user_id=k.user_id )' . "\n" |
1259 . ' ON ( u.user_id=k.user_id )' . "\n" |
1239 . ' LEFT JOIN '.table_prefix.'users_extra AS x' . "\n" |
1260 . ' LEFT JOIN '.table_prefix.'users_extra AS x' . "\n" |
1240 . ' ON ( u.user_id=x.user_id OR x.user_id IS NULL )' . "\n" |
1261 . ' ON ( u.user_id=x.user_id OR x.user_id IS NULL )' . "\n" |
2350 } |
2371 } |
2351 } |
2372 } |
2352 |
2373 |
2353 // Yay! We're done |
2374 // Yay! We're done |
2354 return 'success'; |
2375 return 'success'; |
|
2376 } |
|
2377 |
|
2378 # |
|
2379 # USER RANKS |
|
2380 # |
|
2381 |
|
2382 /** |
|
2383 * SYNOPSIS OF THE RANK SYSTEM |
|
2384 * Enano's rank logic calculates a user's rank based on a precedence scale. The way things are checked is: |
|
2385 * 1. Check to see if the user has a specific rank assigned. Use that if possible. |
|
2386 * 2. Check the user's primary group to see if it specifies a rank. Use that if possible. |
|
2387 * 3. Check the other groups a user is in. If one that has a custom rank is encountered, use that rank. |
|
2388 * 4. See if the user's user level has a specific rank hard-coded to be associated with it. (Always overrideable as can be seen above) |
|
2389 * 5. Use the "member" rank |
|
2390 */ |
|
2391 |
|
2392 /** |
|
2393 * Generates a textual SQL query for fetching rank data to be sent to calculate_user_rank(). |
|
2394 * @param string Text to append, possibly a WHERE clause or so |
|
2395 * @return string |
|
2396 */ |
|
2397 |
|
2398 function generate_rank_sql($append = '') |
|
2399 { |
|
2400 // Generate level-to-rank associations |
|
2401 $assoc = array(); |
|
2402 foreach ( $this->level_rank_table as $level => $rank ) |
|
2403 { |
|
2404 $assoc[] = " ( u.user_level = $level AND rl.rank_id = $rank )"; |
|
2405 } |
|
2406 $assoc = implode(" OR\n", $assoc) . "\n"; |
|
2407 |
|
2408 $gid_col = ( ENANO_DBLAYER == 'PGSQL' ) ? |
|
2409 'array_to_string(array_accum(m.group_id), \',\') AS group_list' : |
|
2410 'GROUP_CONCAT(m.group_id) AS group_list'; |
|
2411 |
|
2412 // The actual query |
|
2413 $sql = "SELECT u.user_id, u.username, u.user_level, u.user_group, u.user_rank, u.user_title, g.group_rank,\n" |
|
2414 . " COALESCE(ru.rank_id, rg.rank_id, rl.rank_id, rd.rank_id ) AS rank_id,\n" |
|
2415 . " COALESCE(ru.rank_title, rg.rank_title, rl.rank_title, rd.rank_title) AS rank_title,\n" |
|
2416 . " COALESCE(ru.rank_style, rg.rank_style, rl.rank_style, rd.rank_style) AS rank_style,\n" |
|
2417 . " ( ru.rank_id IS NULL AND rg.rank_id IS NULL ) AS using_default," |
|
2418 . " ( ru.rank_id IS NULL AND rg.rank_id IS NOT NULL ) AS using_group," |
|
2419 . " $gid_col\n" |
|
2420 . " FROM " . table_prefix . "users AS u\n" |
|
2421 . " LEFT JOIN groups AS g\n" |
|
2422 . " ON ( g.group_id = u.user_group )\n" |
|
2423 . " LEFT JOIN " . table_prefix . "group_members AS m\n" |
|
2424 . " ON ( u.user_id = m.user_id )\n" |
|
2425 . " LEFT JOIN ranks AS ru\n" |
|
2426 . " ON ( u.user_rank = ru.rank_id )\n" |
|
2427 . " LEFT JOIN ranks AS rg\n" |
|
2428 . " ON ( g.group_rank = rg.rank_id )\n" |
|
2429 . " LEFT JOIN ranks AS rl\n" |
|
2430 . " ON (\n" |
|
2431 . $assoc |
|
2432 . " )\n" |
|
2433 . " LEFT JOIN ranks AS rd\n" |
|
2434 . " ON ( rd.rank_id = 1 )\n" |
|
2435 . " GROUP BY u.user_id, u.username, u.user_level, u.user_group, u.user_rank, u.user_title, g.group_rank,\n" |
|
2436 . " ru.rank_id, ru.rank_title, ru.rank_style,rg.rank_id, rg.rank_title, rg.rank_style,\n" |
|
2437 . " rl.rank_id, rl.rank_title, rl.rank_style,rd.rank_id, rd.rank_title, rd.rank_style$append;"; |
|
2438 |
|
2439 return $sql; |
|
2440 } |
|
2441 |
|
2442 /** |
|
2443 * Returns an associative array with a user's rank information. |
|
2444 * The array will contain the following values: |
|
2445 * username: string The user's username |
|
2446 * user_id: integer Numerical user ID |
|
2447 * rank_id: integer Numerical rank ID |
|
2448 * rank: string The user's current rank |
|
2449 * title: string The user's custom user title if applicable; should be displayed one line below the rank |
|
2450 * style: string CSS for the username |
|
2451 * @param int|string Username *or* user ID |
|
2452 * @return array or false on failure |
|
2453 */ |
|
2454 |
|
2455 function get_user_rank($id) |
|
2456 { |
|
2457 global $db, $session, $paths, $template, $plugins; // Common objects |
|
2458 global $lang; |
|
2459 global $user_ranks; |
|
2460 // cache info if possible |
|
2461 static $_cache = array(); |
|
2462 |
|
2463 if ( is_int($id) ) |
|
2464 $col = "user_id = $id"; |
|
2465 else if ( is_string($id) ) |
|
2466 $col = ENANO_SQLFUNC_LOWERCASE . "(username) = " . ENANO_SQLFUNC_LOWERCASE . "('" . $db->escape($id) . "')"; |
|
2467 else |
|
2468 // invalid parameter |
|
2469 return false; |
|
2470 |
|
2471 // check the cache |
|
2472 if ( isset($_cache[$id]) ) |
|
2473 return $_cache[$id]; |
|
2474 |
|
2475 // check the disk cache |
|
2476 if ( is_int($id) ) |
|
2477 { |
|
2478 if ( isset($user_ranks[$id]) ) |
|
2479 { |
|
2480 $_cache[$id] =& $user_ranks[$id]; |
|
2481 return $user_ranks[$id]; |
|
2482 } |
|
2483 } |
|
2484 else if ( is_string($id) ) |
|
2485 { |
|
2486 foreach ( $user_ranks as $key => $valarray ) |
|
2487 { |
|
2488 if ( is_string($key) && strtolower($key) == strtolower($id) ) |
|
2489 { |
|
2490 $_cache[$id] = $valarray; |
|
2491 return $valarray; |
|
2492 } |
|
2493 } |
|
2494 } |
|
2495 |
|
2496 $sql = $this->generate_rank_sql("\n WHERE $col"); |
|
2497 |
|
2498 $q = $this->sql($sql); |
|
2499 // any results? |
|
2500 if ( $db->numrows() < 1 ) |
|
2501 { |
|
2502 // nuttin'. |
|
2503 $db->free_result(); |
|
2504 $_cache[$id] = false; |
|
2505 return false; |
|
2506 } |
|
2507 |
|
2508 // Found something. |
|
2509 $row = $db->fetchrow(); |
|
2510 $db->free_result(); |
|
2511 |
|
2512 $row = $this->calculate_user_rank($row); |
|
2513 |
|
2514 $_cache[$id] = $row; |
|
2515 return $row; |
|
2516 } |
|
2517 |
|
2518 /** |
|
2519 * Performs the actual rank calculation based on the contents of a row. |
|
2520 * @param array |
|
2521 * @return array |
|
2522 */ |
|
2523 |
|
2524 function calculate_user_rank($row) |
|
2525 { |
|
2526 global $db, $session, $paths, $template, $plugins; // Common objects |
|
2527 global $lang; |
|
2528 |
|
2529 static $rank_cache = array(); |
|
2530 static $group_ranks = array(); |
|
2531 |
|
2532 // try to cache that rank info |
|
2533 if ( !isset($rank_cache[ intval($row['rank_id']) ]) && $row['rank_id'] ) |
|
2534 { |
|
2535 $rank_cache[ intval($row['rank_id']) ] = array( |
|
2536 'rank_id' => intval($row['rank_id']), |
|
2537 'rank_title' => intval($row['rank_title']), |
|
2538 'rank_style' => intval($row['rank_style']) |
|
2539 ); |
|
2540 } |
|
2541 // cache group info (if appropriate) |
|
2542 if ( $row['using_group'] && !isset($group_ranks[ intval($row['user_group']) ]) ) |
|
2543 { |
|
2544 $group_ranks[ intval($row['user_group']) ] = intval($row['group_rank_id']); |
|
2545 } |
|
2546 |
|
2547 // sanitize and process the as-of-yet rank data |
|
2548 $row['rank_id'] = intval($row["rank_id"]); |
|
2549 $row['rank_title'] = $row["rank_title"]; |
|
2550 |
|
2551 // if we're falling back to some default, then see if we can use one of the user's other groups |
|
2552 if ( $row['using_default'] && !empty($row['group_list']) ) |
|
2553 { |
|
2554 $group_list = explode(',', $row['group_list']); |
|
2555 if ( array_walk($group_list, 'intval') ) |
|
2556 { |
|
2557 // go through the group list and see if any of them has a rank assigned |
|
2558 foreach ( $group_list as $group_id ) |
|
2559 { |
|
2560 // cached in RAM? Preferably use that. |
|
2561 if ( !isset($group_ranks[$group_id]) ) |
|
2562 { |
|
2563 // Not cached - grab it |
|
2564 $q = $this->sql('SELECT group_rank FROM ' . table_prefix . "groups WHERE group_id = $group_id;"); |
|
2565 if ( $db->numrows() < 1 ) |
|
2566 { |
|
2567 $db->free_result(); |
|
2568 continue; |
|
2569 } |
|
2570 list($result) = $db->fetchrow_num(); |
|
2571 $db->free_result(); |
|
2572 |
|
2573 if ( $result === null || $result < 1 ) |
|
2574 { |
|
2575 $group_ranks[$group_id] = false; |
|
2576 } |
|
2577 else |
|
2578 { |
|
2579 $group_ranks[$group_id] = intval($result); |
|
2580 } |
|
2581 } |
|
2582 // we've got it now |
|
2583 if ( $group_ranks[$group_id] ) |
|
2584 { |
|
2585 // found a group with a rank assigned |
|
2586 // so get the rank info |
|
2587 $rank_id =& $group_ranks[$group_id]; |
|
2588 if ( !isset($rank_cache[$rank_id]) ) |
|
2589 { |
|
2590 $q = $this->sql('SELECT rank_id, rank_title, rank_style FROM ' . table_prefix . "ranks WHERE rank_id = $rank_id;"); |
|
2591 if ( $db->numrows() < 1 ) |
|
2592 { |
|
2593 $db->free_result(); |
|
2594 continue; |
|
2595 } |
|
2596 $rank_cache[$rank_id] = $db->fetchrow(); |
|
2597 $db->free_result(); |
|
2598 } |
|
2599 // set the final rank parameters |
|
2600 // die("found member-of-group exception with uid {$row['user_id']} gid $group_id rid $rank_id rt {$rank_cache[$rank_id]['rank_title']}"); |
|
2601 $row['rank_id'] = $rank_id; |
|
2602 $row['rank_title'] = $rank_cache[$rank_id]['rank_title']; |
|
2603 $row['rank_style'] = $rank_cache[$rank_id]['rank_style']; |
|
2604 break; |
|
2605 } |
|
2606 } |
|
2607 } |
|
2608 } |
|
2609 |
|
2610 if ( $row['user_title'] === NULL ) |
|
2611 $row['user_title'] = false; |
|
2612 |
|
2613 $row['user_id'] = intval($row['user_id']); |
|
2614 $row['user_level'] = intval($row['user_level']); |
|
2615 $row['user_group'] = intval($row['user_group']); |
|
2616 |
|
2617 unset($row['user_rank'], $row['group_rank'], $row['group_list'], $row['using_default'], $row['using_group'], $row['user_level'], $row['user_group'], $row['username']); |
|
2618 return $row; |
2355 } |
2619 } |
2356 |
2620 |
2357 # |
2621 # |
2358 # Access Control Lists |
2622 # Access Control Lists |
2359 # |
2623 # |