[ Index ] |
PHP Cross Reference of phpBB 3.0 Beta 3 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * @package phpBB3 5 * @version $Id: functions_user.php,v 1.146 2006/11/12 15:35:43 acydburn Exp $ 6 * @copyright (c) 2005 phpBB Group 7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License 8 * 9 */ 10 11 /** 12 * Obtain user_ids from usernames or vice versa. Returns false on 13 * success else the error string 14 */ 15 function user_get_id_name(&$user_id_ary, &$username_ary, $only_active = false) 16 { 17 global $db; 18 19 // Are both arrays already filled? Yep, return else 20 // are neither array filled? 21 if ($user_id_ary && $username_ary) 22 { 23 return false; 24 } 25 else if (!$user_id_ary && !$username_ary) 26 { 27 return 'NO_USERS'; 28 } 29 30 $which_ary = ($user_id_ary) ? 'user_id_ary' : 'username_ary'; 31 32 if ($$which_ary && !is_array($$which_ary)) 33 { 34 $$which_ary = array($$which_ary); 35 } 36 37 $sql_in = ($which_ary == 'user_id_ary') ? array_map('intval', $$which_ary) : array_map('utf8_clean_string', $$which_ary); 38 unset($$which_ary); 39 40 $user_id_ary = $username_ary = array(); 41 42 // Grab the user id/username records 43 $sql_where = ($which_ary == 'user_id_ary') ? 'user_id' : 'username_clean'; 44 $sql = 'SELECT user_id, username 45 FROM ' . USERS_TABLE . ' 46 WHERE ' . $db->sql_in_set($sql_where, $sql_in); 47 48 if ($only_active) 49 { 50 $sql .= ' AND user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; 51 } 52 53 $result = $db->sql_query($sql); 54 55 if (!($row = $db->sql_fetchrow($result))) 56 { 57 $db->sql_freeresult($result); 58 return 'NO_USERS'; 59 } 60 61 do 62 { 63 $username_ary[$row['user_id']] = $row['username']; 64 $user_id_ary[] = $row['user_id']; 65 } 66 while ($row = $db->sql_fetchrow($result)); 67 $db->sql_freeresult($result); 68 69 return false; 70 } 71 72 /** 73 * Get latest registered username and update database to reflect it 74 */ 75 function update_last_username() 76 { 77 global $db; 78 79 // Get latest username 80 $sql = 'SELECT user_id, username 81 FROM ' . USERS_TABLE . ' 82 WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ') 83 ORDER BY user_id DESC'; 84 $result = $db->sql_query_limit($sql, 1); 85 $row = $db->sql_fetchrow($result); 86 $db->sql_freeresult($result); 87 88 if ($row) 89 { 90 set_config('newest_user_id', $row['user_id'], true); 91 set_config('newest_username', $row['username'], true); 92 } 93 } 94 95 /** 96 * Updates a username across all relevant tables/fields 97 * 98 * @param string $old_name the old/current username 99 * @param string $new_name the new username 100 */ 101 function user_update_name($old_name, $new_name) 102 { 103 global $config, $db, $cache; 104 105 $update_ary = array( 106 FORUMS_TABLE => array('forum_last_poster_name'), 107 MODERATOR_CACHE_TABLE => array('username'), 108 POSTS_TABLE => array('post_username'), 109 TOPICS_TABLE => array('topic_first_poster_name', 'topic_last_poster_name'), 110 ); 111 112 foreach ($update_ary as $table => $field_ary) 113 { 114 foreach ($field_ary as $field) 115 { 116 $sql = "UPDATE $table 117 SET $field = '" . $db->sql_escape($new_name) . "' 118 WHERE $field = '" . $db->sql_escape($old_name) . "'"; 119 $db->sql_query($sql); 120 } 121 } 122 123 if ($config['newest_username'] == $old_name) 124 { 125 set_config('newest_username', $new_name, true); 126 } 127 } 128 129 /** 130 * Add User 131 */ 132 function user_add($user_row, $cp_data = false) 133 { 134 global $db, $user, $auth, $config, $phpbb_root_path, $phpEx; 135 136 if (empty($user_row['username']) || !isset($user_row['group_id']) || !isset($user_row['user_email']) || !isset($user_row['user_type'])) 137 { 138 return false; 139 } 140 141 $sql_ary = array( 142 'username' => $user_row['username'], 143 'username_clean' => utf8_clean_string($user_row['username']), 144 'user_password' => (isset($user_row['user_password'])) ? $user_row['user_password'] : '', 145 'user_email' => $user_row['user_email'], 146 'user_email_hash' => (int) crc32(strtolower($user_row['user_email'])) . strlen($user_row['user_email']), 147 'group_id' => $user_row['group_id'], 148 'user_type' => $user_row['user_type'], 149 ); 150 151 // These are the additional vars able to be specified 152 $additional_vars = array( 153 'user_permissions' => '', 154 'user_timezone' => $config['board_timezone'], 155 'user_dateformat' => $config['default_dateformat'], 156 'user_lang' => $config['default_lang'], 157 'user_style' => $config['default_style'], 158 'user_allow_pm' => 1, 159 'user_actkey' => '', 160 'user_ip' => '', 161 'user_regdate' => time(), 162 'user_passchg' => time(), 163 164 'user_inactive_reason' => 0, 165 'user_inactive_time' => 0, 166 'user_lastmark' => time(), 167 'user_lastvisit' => 0, 168 'user_lastpost_time' => 0, 169 'user_lastpage' => '', 170 'user_posts' => 0, 171 'user_dst' => 0, 172 'user_colour' => '', 173 'user_interests' => '', 174 'user_avatar' => '', 175 'user_avatar_type' => 0, 176 'user_avatar_width' => 0, 177 'user_avatar_height' => 0, 178 'user_new_privmsg' => 0, 179 'user_unread_privmsg' => 0, 180 'user_last_privmsg' => 0, 181 'user_message_rules' => 0, 182 'user_full_folder' => PRIVMSGS_NO_BOX, 183 'user_emailtime' => 0, 184 185 'user_notify' => 0, 186 'user_notify_pm' => 1, 187 'user_notify_type' => NOTIFY_EMAIL, 188 'user_allow_pm' => 1, 189 'user_allow_viewonline' => 1, 190 'user_allow_viewemail' => 1, 191 'user_allow_massemail' => 1, 192 193 'user_sig' => '', 194 'user_sig_bbcode_uid' => '', 195 'user_sig_bbcode_bitfield' => '', 196 ); 197 198 // Now fill the sql array with not required variables 199 foreach ($additional_vars as $key => $default_value) 200 { 201 $sql_ary[$key] = (isset($user_row[$key])) ? $user_row[$key] : $default_value; 202 } 203 204 // Any additional variables in $user_row not covered above? 205 $remaining_vars = array_diff(array_keys($user_row), array_keys($sql_ary)); 206 207 // Now fill our sql array with the remaining vars 208 if (sizeof($remaining_vars)) 209 { 210 foreach ($remaining_vars as $key) 211 { 212 $sql_ary[$key] = $user_row[$key]; 213 } 214 } 215 216 $sql = 'INSERT INTO ' . USERS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); 217 $db->sql_query($sql); 218 219 $user_id = $db->sql_nextid(); 220 221 // Insert Custom Profile Fields 222 if ($cp_data !== false && sizeof($cp_data)) 223 { 224 $cp_data['user_id'] = (int) $user_id; 225 226 if (!class_exists('custom_profile')) 227 { 228 include_once($phpbb_root_path . 'includes/functions_profile_fields.' . $phpEx); 229 } 230 231 $sql = 'INSERT INTO ' . PROFILE_FIELDS_DATA_TABLE . ' ' . 232 $db->sql_build_array('INSERT', custom_profile::build_insert_sql_array($cp_data)); 233 $db->sql_query($sql); 234 } 235 236 // Place into appropriate group... 237 $sql = 'INSERT INTO ' . USER_GROUP_TABLE . ' ' . $db->sql_build_array('INSERT', array( 238 'user_id' => (int) $user_id, 239 'group_id' => (int) $user_row['group_id'], 240 'user_pending' => 0) 241 ); 242 $db->sql_query($sql); 243 244 // Now make it the users default group... 245 group_set_user_default($user_row['group_id'], array($user_id)); 246 247 // set the newest user and adjust the user count if the user is a normal user and no activation mail is sent 248 if ($user_row['user_type'] == USER_NORMAL) 249 { 250 set_config('newest_user_id', $user_id, true); 251 set_config('newest_username', $user_row['username'], true); 252 set_config('num_users', $config['num_users'] + 1, true); 253 } 254 255 return $user_id; 256 } 257 258 /** 259 * Remove User 260 */ 261 function user_delete($mode, $user_id, $post_username = false) 262 { 263 global $cache, $config, $db, $user, $auth; 264 global $phpbb_root_path, $phpEx; 265 266 $db->sql_transaction('begin'); 267 268 switch ($mode) 269 { 270 case 'retain': 271 272 if ($post_username === false) 273 { 274 $post_username = $user->lang['GUEST']; 275 } 276 277 $sql = 'UPDATE ' . FORUMS_TABLE . ' 278 SET forum_last_poster_id = ' . ANONYMOUS . ", forum_last_poster_name = '" . $db->sql_escape($post_username) . "', forum_last_poster_colour = '' 279 WHERE forum_last_poster_id = $user_id"; 280 $db->sql_query($sql); 281 282 $sql = 'UPDATE ' . POSTS_TABLE . ' 283 SET poster_id = ' . ANONYMOUS . ", post_username = '" . $db->sql_escape($post_username) . "' 284 WHERE poster_id = $user_id"; 285 $db->sql_query($sql); 286 287 $sql = 'UPDATE ' . POSTS_TABLE . ' 288 SET post_edit_user = ' . ANONYMOUS . " 289 WHERE post_edit_user = $user_id"; 290 $db->sql_query($sql); 291 292 $sql = 'UPDATE ' . TOPICS_TABLE . ' 293 SET topic_poster = ' . ANONYMOUS . ", topic_first_poster_name = '" . $db->sql_escape($post_username) . "', topic_first_poster_colour = '' 294 WHERE topic_poster = $user_id"; 295 $db->sql_query($sql); 296 297 $sql = 'UPDATE ' . TOPICS_TABLE . ' 298 SET topic_last_poster_id = ' . ANONYMOUS . ", topic_last_poster_name = '" . $db->sql_escape($post_username) . "', topic_last_poster_colour = '' 299 WHERE topic_last_poster_id = $user_id"; 300 $db->sql_query($sql); 301 302 // Since we change every post by this author, we need to count this amount towards the anonymous user 303 $sql = 'SELECT user_posts 304 FROM ' . USERS_TABLE . ' 305 WHERE user_id = ' . $user_id; 306 $result = $db->sql_query($sql); 307 $num_posts = (int) $db->sql_fetchfield('user_posts'); 308 $db->sql_freeresult($result); 309 310 // Update the post count for the anonymous user 311 if ($num_posts) 312 { 313 $sql = 'UPDATE ' . USERS_TABLE . ' 314 SET user_posts = user_posts + ' . $num_posts . ' 315 WHERE user_id = ' . ANONYMOUS; 316 $db->sql_query($sql); 317 } 318 break; 319 320 case 'remove': 321 322 if (!function_exists('delete_posts')) 323 { 324 include_once($phpbb_root_path . 'includes/functions_admin.' . $phpEx); 325 } 326 327 $sql = 'SELECT topic_id, COUNT(post_id) AS total_posts 328 FROM ' . POSTS_TABLE . " 329 WHERE poster_id = $user_id 330 GROUP BY topic_id"; 331 $result = $db->sql_query($sql); 332 333 $topic_id_ary = array(); 334 while ($row = $db->sql_fetchrow($result)) 335 { 336 $topic_id_ary[$row['topic_id']] = $row['total_posts']; 337 } 338 $db->sql_freeresult($result); 339 340 if (sizeof($topic_id_ary)) 341 { 342 $sql = 'SELECT topic_id, topic_replies, topic_replies_real 343 FROM ' . TOPICS_TABLE . ' 344 WHERE ' . $db->sql_in_set('topic_id', array_keys($topic_id_ary)); 345 $result = $db->sql_query($sql); 346 347 $del_topic_ary = array(); 348 while ($row = $db->sql_fetchrow($result)) 349 { 350 if (max($row['topic_replies'], $row['topic_replies_real']) + 1 == $topic_id_ary[$row['topic_id']]) 351 { 352 $del_topic_ary[] = $row['topic_id']; 353 } 354 } 355 $db->sql_freeresult($result); 356 357 if (sizeof($del_topic_ary)) 358 { 359 $sql = 'DELETE FROM ' . TOPICS_TABLE . ' 360 WHERE ' . $db->sql_in_set('topic_id', $del_topic_ary); 361 $db->sql_query($sql); 362 } 363 } 364 365 // Delete posts, attachments, etc. 366 delete_posts('poster_id', $user_id); 367 368 break; 369 } 370 371 $table_ary = array(USERS_TABLE, USER_GROUP_TABLE, TOPICS_WATCH_TABLE, FORUMS_WATCH_TABLE, ACL_USERS_TABLE, TOPICS_TRACK_TABLE, TOPICS_POSTED_TABLE, FORUMS_TRACK_TABLE, PROFILE_FIELDS_DATA_TABLE, MODERATOR_CACHE_TABLE); 372 373 foreach ($table_ary as $table) 374 { 375 $sql = "DELETE FROM $table 376 WHERE user_id = $user_id"; 377 $db->sql_query($sql); 378 } 379 380 $cache->destroy('sql', MODERATOR_CACHE_TABLE); 381 382 include_once($phpbb_root_path . 'includes/functions_privmsgs.' . $phpEx); 383 384 // Remove any undelivered mails... 385 $sql = 'SELECT msg_id, user_id 386 FROM ' . PRIVMSGS_TO_TABLE . ' 387 WHERE author_id = ' . $user_id . ' 388 AND folder_id = ' . PRIVMSGS_NO_BOX; 389 $result = $db->sql_query($sql); 390 391 $undelivered_msg = $undelivered_user = array(); 392 while ($row = $db->sql_fetchrow($result)) 393 { 394 $undelivered_msg[] = $row['msg_id']; 395 $undelivered_user[$row['user_id']][] = true; 396 } 397 $db->sql_freeresult($result); 398 399 if (sizeof($undelivered_msg)) 400 { 401 $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' 402 WHERE ' . $db->sql_in_set('msg_id', $undelivered_msg); 403 $db->sql_query($sql); 404 } 405 406 $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' 407 WHERE author_id = ' . $user_id . ' 408 AND folder_id = ' . PRIVMSGS_NO_BOX; 409 $db->sql_query($sql); 410 411 // Delete all to-informations 412 $sql = 'DELETE FROM ' . PRIVMSGS_TO_TABLE . ' 413 WHERE user_id = ' . $user_id; 414 $db->sql_query($sql); 415 416 // Set the remaining author id to anonymous - this way users are still able to read messages from users being removed 417 $sql = 'UPDATE ' . PRIVMSGS_TO_TABLE . ' 418 SET author_id = ' . ANONYMOUS . ' 419 WHERE author_id = ' . $user_id; 420 $db->sql_query($sql); 421 422 $sql = 'UPDATE ' . PRIVMSGS_TABLE . ' 423 SET author_id = ' . ANONYMOUS . ' 424 WHERE author_id = ' . $user_id; 425 $db->sql_query($sql); 426 427 foreach ($undelivered_user as $_user_id => $ary) 428 { 429 if ($_user_id == $user_id) 430 { 431 continue; 432 } 433 434 $sql = 'UPDATE ' . USERS_TABLE . ' 435 SET user_new_privmsg = user_new_privmsg - ' . sizeof($ary) . ', 436 user_unread_privmsg = user_unread_privmsg - ' . sizeof($ary) . ' 437 WHERE user_id = ' . $_user_id; 438 $db->sql_query($sql); 439 } 440 441 // Reset newest user info if appropriate 442 if ($config['newest_user_id'] == $user_id) 443 { 444 update_last_username(); 445 } 446 447 set_config('num_users', $config['num_users'] - 1, true); 448 449 $db->sql_transaction('commit'); 450 451 return false; 452 } 453 454 /** 455 * Flips user_type from active to inactive and vice versa, handles group membership updates 456 * 457 * @param string $mode can be flip for flipping from active/inactive, activate or deactivate 458 */ 459 function user_active_flip($mode, $user_id_ary, $reason = INACTIVE_MANUAL) 460 { 461 global $config, $db, $user, $auth; 462 463 $deactivated = $activated = 0; 464 $sql_statements = array(); 465 466 if (!is_array($user_id_ary)) 467 { 468 $user_id_ary = array($user_id_ary); 469 } 470 471 if (!sizeof($user_id_ary)) 472 { 473 return; 474 } 475 476 $sql = 'SELECT user_id, group_id, user_type, user_inactive_reason 477 FROM ' . USERS_TABLE . ' 478 WHERE ' . $db->sql_in_set('user_id', $user_id_ary); 479 $result = $db->sql_query($sql); 480 481 while ($row = $db->sql_fetchrow($result)) 482 { 483 $sql_ary = array(); 484 485 if ($row['user_type'] == USER_IGNORE || $row['user_type'] == USER_FOUNDER || 486 ($mode == 'activate' && $row['user_type'] != USER_INACTIVE) || 487 ($mode == 'deactivate' && $row['user_type'] == USER_INACTIVE)) 488 { 489 continue; 490 } 491 492 if ($row['user_type'] == USER_INACTIVE) 493 { 494 $activated++; 495 } 496 else 497 { 498 $deactivated++; 499 500 // Remove the users session key... 501 $user->reset_login_keys($row['user_id']); 502 } 503 504 $sql_ary += array( 505 'user_type' => ($row['user_type'] == USER_NORMAL) ? USER_INACTIVE : USER_NORMAL, 506 'user_inactive_time' => ($row['user_type'] == USER_NORMAL) ? time() : 0, 507 'user_inactive_reason' => ($row['user_type'] == USER_NORMAL) ? $reason : 0, 508 ); 509 510 $sql_statements[$row['user_id']] = $sql_ary; 511 } 512 $db->sql_freeresult($result); 513 514 if (sizeof($sql_statements)) 515 { 516 foreach ($sql_statements as $user_id => $sql_ary) 517 { 518 $sql = 'UPDATE ' . USERS_TABLE . ' 519 SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' 520 WHERE user_id = ' . $user_id; 521 $db->sql_query($sql); 522 } 523 524 $auth->acl_clear_prefetch(array_keys($sql_statements)); 525 } 526 527 if ($deactivated) 528 { 529 set_config('num_users', $config['num_users'] - $deactivated, true); 530 } 531 532 if ($activated) 533 { 534 set_config('num_users', $config['num_users'] + $activated, true); 535 } 536 537 // Update latest username 538 update_last_username(); 539 } 540 541 /** 542 * Add a ban or ban exclusion to the banlist. Bans either a user, an IP or an email address 543 * 544 * @param string $mode Type of ban. One of the following: user, ip, email 545 * @param mixed $ban Banned entity. Either string or array with usernames, ips or email addresses 546 * @param int $ban_len Ban length in minutes 547 * @param string $ban_len_other Ban length as a date (YYYY-MM-DD) 548 * @param boolean $ban_exclude Exclude these entities from banning? 549 * @param string $ban_reason String describing the reason for this ban 550 * @return boolean 551 */ 552 function user_ban($mode, $ban, $ban_len, $ban_len_other, $ban_exclude, $ban_reason, $ban_give_reason = '') 553 { 554 global $db, $user, $auth; 555 556 // Delete stale bans 557 $sql = 'DELETE FROM ' . BANLIST_TABLE . ' 558 WHERE ban_end < ' . time() . ' 559 AND ban_end <> 0'; 560 $db->sql_query($sql); 561 562 $ban_list = (!is_array($ban)) ? array_unique(explode("\n", $ban)) : $ban; 563 $ban_list_log = implode(', ', $ban_list); 564 565 $current_time = time(); 566 567 // Set $ban_end to the unix time when the ban should end. 0 is a permanent ban. 568 if ($ban_len) 569 { 570 if ($ban_len != -1 || !$ban_len_other) 571 { 572 $ban_end = max($current_time, $current_time + ($ban_len) * 60); 573 } 574 else 575 { 576 $ban_other = explode('-', $ban_len_other); 577 $ban_end = max($current_time, gmmktime(0, 0, 0, $ban_other[1], $ban_other[2], $ban_other[0])); 578 } 579 } 580 else 581 { 582 $ban_end = 0; 583 } 584 585 $founder = array(); 586 587 if (!$ban_exclude) 588 { 589 // Create a list of founder... 590 $sql = 'SELECT user_id, user_email 591 FROM ' . USERS_TABLE . ' 592 WHERE user_type = ' . USER_FOUNDER; 593 $result = $db->sql_query($sql); 594 595 while ($row = $db->sql_fetchrow($result)) 596 { 597 $founder[$row['user_id']] = $row['user_email']; 598 } 599 $db->sql_freeresult($result); 600 } 601 602 $banlist_ary = array(); 603 604 switch ($mode) 605 { 606 case 'user': 607 $type = 'ban_userid'; 608 609 if (in_array('*', $ban_list)) 610 { 611 // Ban all users (it's a good thing that you can exclude people) 612 $banlist_ary[] = '*'; 613 } 614 else 615 { 616 // Select the relevant user_ids. 617 $sql_usernames = array(); 618 619 foreach ($ban_list as $username) 620 { 621 $username = trim($username); 622 if ($username != '') 623 { 624 $sql_usernames[] = utf8_clean_string($username); 625 } 626 } 627 628 // Make sure we have been given someone to ban 629 if (!sizeof($sql_usernames)) 630 { 631 trigger_error($user->lang['NO_USER_SPECIFIED']); 632 } 633 634 $sql = 'SELECT user_id 635 FROM ' . USERS_TABLE . ' 636 WHERE ' . $db->sql_in_set('username_clean', $sql_usernames); 637 638 // Do not allow banning yourself 639 if (sizeof($founder)) 640 { 641 $sql .= ' AND ' . $db->sql_in_set('user_id', array_merge(array_keys($founder), array($user->data['user_id'])), true); 642 } 643 else 644 { 645 $sql .= ' AND user_id <> ' . $user->data['user_id']; 646 } 647 648 $result = $db->sql_query($sql); 649 650 if ($row = $db->sql_fetchrow($result)) 651 { 652 do 653 { 654 $banlist_ary[] = $row['user_id']; 655 } 656 while ($row = $db->sql_fetchrow($result)); 657 } 658 else 659 { 660 trigger_error($user->lang['NO_USERS']); 661 } 662 $db->sql_freeresult($result); 663 } 664 break; 665 666 case 'ip': 667 $type = 'ban_ip'; 668 669 foreach ($ban_list as $ban_item) 670 { 671 if (preg_match('#^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})[ ]*\-[ ]*([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$#', trim($ban_item), $ip_range_explode)) 672 { 673 // This is an IP range 674 // Don't ask about all this, just don't ask ... ! 675 $ip_1_counter = $ip_range_explode[1]; 676 $ip_1_end = $ip_range_explode[5]; 677 678 while ($ip_1_counter <= $ip_1_end) 679 { 680 $ip_2_counter = ($ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[2] : 0; 681 $ip_2_end = ($ip_1_counter < $ip_1_end) ? 254 : $ip_range_explode[6]; 682 683 if ($ip_2_counter == 0 && $ip_2_end == 254) 684 { 685 $ip_2_counter = 256; 686 $ip_2_fragment = 256; 687 688 $banlist_ary[] = "$ip_1_counter.*"; 689 } 690 691 while ($ip_2_counter <= $ip_2_end) 692 { 693 $ip_3_counter = ($ip_2_counter == $ip_range_explode[2] && $ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[3] : 0; 694 $ip_3_end = ($ip_2_counter < $ip_2_end || $ip_1_counter < $ip_1_end) ? 254 : $ip_range_explode[7]; 695 696 if ($ip_3_counter == 0 && $ip_3_end == 254) 697 { 698 $ip_3_counter = 256; 699 $ip_3_fragment = 256; 700 701 $banlist_ary[] = "$ip_1_counter.$ip_2_counter.*"; 702 } 703 704 while ($ip_3_counter <= $ip_3_end) 705 { 706 $ip_4_counter = ($ip_3_counter == $ip_range_explode[3] && $ip_2_counter == $ip_range_explode[2] && $ip_1_counter == $ip_range_explode[1]) ? $ip_range_explode[4] : 0; 707 $ip_4_end = ($ip_3_counter < $ip_3_end || $ip_2_counter < $ip_2_end) ? 254 : $ip_range_explode[8]; 708 709 if ($ip_4_counter == 0 && $ip_4_end == 254) 710 { 711 $ip_4_counter = 256; 712 $ip_4_fragment = 256; 713 714 $banlist_ary[] = "$ip_1_counter.$ip_2_counter.$ip_3_counter.*"; 715 } 716 717 while ($ip_4_counter <= $ip_4_end) 718 { 719 $banlist_ary[] = "$ip_1_counter.$ip_2_counter.$ip_3_counter.$ip_4_counter"; 720 $ip_4_counter++; 721 } 722 $ip_3_counter++; 723 } 724 $ip_2_counter++; 725 } 726 $ip_1_counter++; 727 } 728 } 729 else if (preg_match('#^([\w\-_]\.?){2,}$#is', trim($ban_item))) 730 { 731 // hostname 732 $ip_ary = gethostbynamel(trim($ban_item)); 733 734 foreach ($ip_ary as $ip) 735 { 736 if ($ip) 737 { 738 $banlist_ary[] = $ip; 739 } 740 } 741 } 742 else if (preg_match('#^([0-9]{1,3})\.([0-9\*]{1,3})\.([0-9\*]{1,3})\.([0-9\*]{1,3})$#', trim($ban_item)) || preg_match('#^[a-f0-9:]+\*?$#i', trim($ban_item))) 743 { 744 // Normal IP address 745 $banlist_ary[] = trim($ban_item); 746 } 747 else if (preg_match('#^\*$#', trim($ban_item))) 748 { 749 // Ban all IPs 750 $banlist_ary[] = "*"; 751 } 752 else 753 { 754 trigger_error('NO_IPS_DEFINED'); 755 } 756 } 757 break; 758 759 case 'email': 760 $type = 'ban_email'; 761 762 foreach ($ban_list as $ban_item) 763 { 764 $ban_item = trim($ban_item); 765 766 if (preg_match('#^.*?@*|(([a-z0-9\-]+\.)+([a-z]{2,3}))$#i', $ban_item)) 767 { 768 if (!sizeof($founder) || !in_array($ban_item, $founder)) 769 { 770 $banlist_ary[] = $ban_item; 771 } 772 } 773 } 774 775 if (sizeof($ban_list) == 0) 776 { 777 trigger_error('NO_EMAILS_DEFINED'); 778 } 779 break; 780 781 default: 782 trigger_error('NO_MODE'); 783 break; 784 } 785 786 // Fetch currently set bans of the specified type and exclude state. Prevent duplicate bans. 787 $sql = "SELECT $type 788 FROM " . BANLIST_TABLE . " 789 WHERE $type <> '' 790 AND ban_exclude = $ban_exclude"; 791 $result = $db->sql_query($sql); 792 793 if ($row = $db->sql_fetchrow($result)) 794 { 795 $banlist_ary_tmp = array(); 796 do 797 { 798 switch ($mode) 799 { 800 case 'user': 801 $banlist_ary_tmp[] = $row['ban_userid']; 802 break; 803 804 case 'ip': 805 $banlist_ary_tmp[] = $row['ban_ip']; 806 break; 807 808 case 'email': 809 $banlist_ary_tmp[] = $row['ban_email']; 810 break; 811 } 812 } 813 while ($row = $db->sql_fetchrow($result)); 814 815 $banlist_ary = array_unique(array_diff($banlist_ary, $banlist_ary_tmp)); 816 unset($banlist_ary_tmp); 817 } 818 $db->sql_freeresult($result); 819 820 // We have some entities to ban 821 if (sizeof($banlist_ary)) 822 { 823 $sql_ary = array(); 824 825 foreach ($banlist_ary as $ban_entry) 826 { 827 $sql_ary[] = array( 828 $type => $ban_entry, 829 'ban_start' => $current_time, 830 'ban_end' => $ban_end, 831 'ban_exclude' => $ban_exclude, 832 'ban_reason' => $ban_reason, 833 'ban_give_reason' => $ban_give_reason, 834 ); 835 } 836 837 $db->sql_multi_insert(BANLIST_TABLE, $sql_ary); 838 839 // If we are banning we want to logout anyone matching the ban 840 if (!$ban_exclude) 841 { 842 switch ($mode) 843 { 844 case 'user': 845 $sql_where = (in_array('*', $banlist_ary)) ? '' : 'WHERE ' . $db->sql_in_set('session_user_id', $banlist_ary); 846 break; 847 848 case 'ip': 849 $sql_where = 'WHERE ' . $db->sql_in_set('session_ip', $banlist_ary); 850 break; 851 852 case 'email': 853 $banlist_ary_sql = array(); 854 855 foreach ($banlist_ary as $ban_entry) 856 { 857 $banlist_ary_sql[] = (string) str_replace('*', '%', $ban_entry); 858 } 859 860 $sql = 'SELECT user_id 861 FROM ' . USERS_TABLE . ' 862 WHERE ' . $db->sql_in_set('user_email', $banlist_ary_sql); 863 $result = $db->sql_query($sql); 864 865 $sql_in = array(); 866 867 if ($row = $db->sql_fetchrow($result)) 868 { 869 do 870 { 871 $sql_in[] = $row['user_id']; 872 } 873 while ($row = $db->sql_fetchrow($result)); 874 875 $sql_where = 'WHERE ' . $db->sql_in_set('session_user_id', $sql_in); 876 } 877 $db->sql_freeresult($result); 878 break; 879 } 880 881 if (isset($sql_where) && $sql_where) 882 { 883 $sql = 'DELETE FROM ' . SESSIONS_TABLE . " 884 $sql_where"; 885 $db->sql_query($sql); 886 887 if ($mode == 'user') 888 { 889 $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . ' ' . ((in_array('*', $banlist_ary)) ? '' : 'WHERE ' . $db->sql_in_set('user_id', $banlist_ary)); 890 $db->sql_query($sql); 891 } 892 } 893 } 894 895 // Update log 896 $log_entry = ($ban_exclude) ? 'LOG_BAN_EXCLUDE_' : 'LOG_BAN_'; 897 add_log('admin', $log_entry . strtoupper($mode), $ban_reason, $ban_list_log); 898 899 return true; 900 } 901 902 // There was nothing to ban/exclude 903 return false; 904 } 905 906 /** 907 * Unban User 908 */ 909 function user_unban($mode, $ban) 910 { 911 global $db, $user, $auth; 912 913 // Delete stale bans 914 $sql = 'DELETE FROM ' . BANLIST_TABLE . ' 915 WHERE ban_end < ' . time() . ' 916 AND ban_end <> 0'; 917 $db->sql_query($sql); 918 919 if (!is_array($ban)) 920 { 921 $ban = array($ban); 922 } 923 924 $unban_sql = array_map('intval', $ban); 925 926 if (sizeof($unban_sql)) 927 { 928 // Grab details of bans for logging information later 929 switch ($mode) 930 { 931 case 'user': 932 $sql = 'SELECT u.username AS unban_info 933 FROM ' . USERS_TABLE . ' u, ' . BANLIST_TABLE . ' b 934 WHERE ' . $db->sql_in_set('b.ban_id', $unban_sql) . ' 935 AND u.user_id = b.ban_userid'; 936 break; 937 938 case 'email': 939 $sql = 'SELECT ban_email AS unban_info 940 FROM ' . BANLIST_TABLE . ' 941 WHERE ' . $db->sql_in_set('ban_id', $unban_sql); 942 break; 943 944 case 'ip': 945 $sql = 'SELECT ban_ip AS unban_info 946 FROM ' . BANLIST_TABLE . ' 947 WHERE ' . $db->sql_in_set('ban_id', $unban_sql); 948 break; 949 } 950 $result = $db->sql_query($sql); 951 952 $l_unban_list = ''; 953 while ($row = $db->sql_fetchrow($result)) 954 { 955 $l_unban_list .= (($l_unban_list != '') ? ', ' : '') . $row['unban_info']; 956 } 957 $db->sql_freeresult($result); 958 959 $sql = 'DELETE FROM ' . BANLIST_TABLE . ' 960 WHERE ' . $db->sql_in_set('ban_id', $unban_sql); 961 $db->sql_query($sql); 962 963 add_log('admin', 'LOG_UNBAN_' . strtoupper($mode), $l_unban_list); 964 } 965 966 return false; 967 } 968 969 /** 970 * Whois facility 971 */ 972 function user_ipwhois($ip) 973 { 974 $ipwhois = ''; 975 976 $match = array( 977 '#RIPE\.NET#is' => 'whois.ripe.net', 978 '#whois\.apnic\.net#is' => 'whois.apnic.net', 979 '#nic\.ad\.jp#is' => 'whois.nic.ad.jp', 980 '#whois\.registro\.br#is' => 'whois.registro.br' 981 ); 982 983 if (($fsk = @fsockopen('whois.arin.net', 43))) 984 { 985 fputs($fsk, "$ip\n"); 986 while (!feof($fsk)) 987 { 988 $ipwhois .= fgets($fsk, 1024); 989 } 990 @fclose($fsk); 991 } 992 993 foreach (array_keys($match) as $server) 994 { 995 if (preg_match($server, $ipwhois)) 996 { 997 $ipwhois = ''; 998 if (($fsk = @fsockopen($match[$server], 43))) 999 { 1000 fputs($fsk, "$ip\n"); 1001 while (!feof($fsk)) 1002 { 1003 $ipwhois .= fgets($fsk, 1024); 1004 } 1005 @fclose($fsk); 1006 } 1007 break; 1008 } 1009 } 1010 1011 return $ipwhois; 1012 } 1013 1014 /** 1015 * Data validation ... used primarily but not exclusively by ucp modules 1016 * 1017 * "Master" function for validating a range of data types 1018 */ 1019 function validate_data($data, $val_ary) 1020 { 1021 $error = array(); 1022 1023 foreach ($val_ary as $var => $val_seq) 1024 { 1025 if (!is_array($val_seq[0])) 1026 { 1027 $val_seq = array($val_seq); 1028 } 1029 1030 foreach ($val_seq as $validate) 1031 { 1032 $function = array_shift($validate); 1033 array_unshift($validate, $data[$var]); 1034 1035 if ($result = call_user_func_array('validate_' . $function, $validate)) 1036 { 1037 $error[] = $result . '_' . strtoupper($var); 1038 } 1039 } 1040 } 1041 1042 return $error; 1043 } 1044 1045 /** 1046 * Validate String 1047 * 1048 * @return boolean|string Either false if validation succeeded or a string which will be used as the error message (with the variable name appended) 1049 */ 1050 function validate_string($string, $optional = false, $min = 0, $max = 0) 1051 { 1052 if (empty($string) && $optional) 1053 { 1054 return false; 1055 } 1056 1057 if ($min && utf8_strlen(htmlspecialchars_decode($string)) < $min) 1058 { 1059 return 'TOO_SHORT'; 1060 } 1061 else if ($max && utf8_strlen(htmlspecialchars_decode($string)) > $max) 1062 { 1063 return 'TOO_LONG'; 1064 } 1065 1066 return false; 1067 } 1068 1069 /** 1070 * Validate Number 1071 * 1072 * @return boolean|string Either false if validation succeeded or a string which will be used as the error message (with the variable name appended) 1073 */ 1074 function validate_num($num, $optional = false, $min = 0, $max = 1E99) 1075 { 1076 if (empty($num) && $optional) 1077 { 1078 return false; 1079 } 1080 1081 if ($num < $min) 1082 { 1083 return 'TOO_SMALL'; 1084 } 1085 else if ($num > $max) 1086 { 1087 return 'TOO_LARGE'; 1088 } 1089 1090 return false; 1091 } 1092 1093 /** 1094 * Validate Match 1095 * 1096 * @return boolean|string Either false if validation succeeded or a string which will be used as the error message (with the variable name appended) 1097 */ 1098 function validate_match($string, $optional = false, $match) 1099 { 1100 if (empty($string) && $optional) 1101 { 1102 return false; 1103 } 1104 1105 if (!preg_match($match, $string)) 1106 { 1107 return 'WRONG_DATA'; 1108 } 1109 1110 return false; 1111 } 1112 1113 /** 1114 * Check to see if the username has been taken, or if it is disallowed. 1115 * Also checks if it includes the " character, which we don't allow in usernames. 1116 * Used for registering, changing names, and posting anonymously with a username 1117 * 1118 * @todo do we really check and disallow the " character in usernames as written above. Has it only be forgotten to include the check? 1119 * @return boolean|string Either false if validation succeeded or a string which will be used as the error message (with the variable name appended) 1120 */ 1121 function validate_username($username) 1122 { 1123 global $config, $db, $user, $cache; 1124 1125 $clean_username = utf8_clean_string($username); 1126 1127 if (utf8_clean_string($user->data['username']) == $clean_username) 1128 { 1129 return false; 1130 } 1131 1132 if (!preg_match('#^' . str_replace('\\\\', '\\', $config['allow_name_chars']) . '$#i', $username) || strpos($username, '"') !== false || strpos($username, '"') !== false) 1133 { 1134 return 'INVALID_CHARS'; 1135 } 1136 1137 $sql = 'SELECT username 1138 FROM ' . USERS_TABLE . " 1139 WHERE username_clean = '" . $db->sql_escape($clean_username) . "'"; 1140 $result = $db->sql_query($sql); 1141 $row = $db->sql_fetchrow($result); 1142 $db->sql_freeresult($result); 1143 1144 if ($row) 1145 { 1146 return 'USERNAME_TAKEN'; 1147 } 1148 1149 $sql = 'SELECT group_name 1150 FROM ' . GROUPS_TABLE . " 1151 WHERE LOWER(group_name) = '" . $db->sql_escape(utf8_strtolower($username)) . "'"; 1152 $result = $db->sql_query($sql); 1153 $row = $db->sql_fetchrow($result); 1154 $db->sql_freeresult($result); 1155 1156 if ($row) 1157 { 1158 return 'USERNAME_TAKEN'; 1159 } 1160 1161 1162 $bad_usernames = $cache->obtain_disallowed_usernames(); 1163 1164 foreach ($bad_usernames as $bad_username) 1165 { 1166 if (preg_match('#^' . $bad_username . '#', $clean_username)) 1167 { 1168 return 'USERNAME_DISALLOWED'; 1169 } 1170 } 1171 1172 $sql = 'SELECT word 1173 FROM ' . WORDS_TABLE; 1174 $result = $db->sql_query($sql); 1175 1176 while ($row = $db->sql_fetchrow($result)) 1177 { 1178 if (preg_match('#(' . str_replace('\*', '.*?', preg_quote($row['word'], '#')) . ')#i', $username)) 1179 { 1180 $db->sql_freeresult($result); 1181 return 'USERNAME_DISALLOWED'; 1182 } 1183 } 1184 $db->sql_freeresult($result); 1185 1186 return false; 1187 } 1188 1189 /** 1190 * Check to see if the password meets the complexity settings 1191 * 1192 * @return boolean|string Either false if validation succeeded or a string which will be used as the error message (with the variable name appended) 1193 */ 1194 function validate_password($password) 1195 { 1196 global $config, $db, $user; 1197 1198 if (!$password) 1199 { 1200 return false; 1201 } 1202 1203 // We only check for existance of characters 1204 if (!preg_match('#' . str_replace('\\\\', '\\', $config['pass_complex']) . '#i', $password)) 1205 { 1206 return 'INVALID_CHARS'; 1207 } 1208 1209 return false; 1210 } 1211 1212 /** 1213 * Check to see if email address is banned or already present in the DB 1214 * 1215 * @return boolean|string Either false if validation succeeded or a string which will be used as the error message (with the variable name appended) 1216 */ 1217 function validate_email($email) 1218 { 1219 global $config, $db, $user; 1220 1221 if (strtolower($user->data['user_email']) == strtolower($email)) 1222 { 1223 return false; 1224 } 1225 1226 if (!preg_match('/^' . get_preg_expression('email') . '$/i', $email)) 1227 { 1228 return 'EMAIL_INVALID'; 1229 } 1230 1231 // Check MX record. 1232 // The idea for this is from reading the UseBB blog/announcement. :) 1233 if ($config['email_check_mx']) 1234 { 1235 list(, $domain) = explode('@', $email); 1236 1237 if (phpbb_checkdnsrr($domain, 'MX') === false) 1238 { 1239 return 'DOMAIN_NO_MX_RECORD'; 1240 } 1241 } 1242 1243 if ($user->check_ban(false, false, $email, true) == true) 1244 { 1245 return 'EMAIL_BANNED'; 1246 } 1247 1248 if (!$config['allow_emailreuse']) 1249 { 1250 $sql = 'SELECT user_email_hash 1251 FROM ' . USERS_TABLE . " 1252 WHERE user_email_hash = " . crc32(strtolower($email)) . strlen($email); 1253 $result = $db->sql_query($sql); 1254 $row = $db->sql_fetchrow($result); 1255 $db->sql_freeresult($result); 1256 1257 if ($row) 1258 { 1259 return 'EMAIL_TAKEN'; 1260 } 1261 } 1262 1263 return false; 1264 } 1265 1266 /** 1267 * Remove avatar 1268 */ 1269 function avatar_delete($mode, $row) 1270 { 1271 global $phpbb_root_path, $config, $db, $user; 1272 1273 // Check if the users avatar is actually *not* a group avatar 1274 if ($mode == 'user') 1275 { 1276 if (strpos($row['user_avatar'], 'g' . $row['group_id'] . '_') === 0 || strpos($row['user_avatar'], $row['user_id'] . '_') !== 0) 1277 { 1278 return false; 1279 } 1280 } 1281 1282 if (file_exists($phpbb_root_path . $config['avatar_path'] . '/' . basename($row[$mode . '_avatar']))) 1283 { 1284 @unlink($phpbb_root_path . $config['avatar_path'] . '/' . basename($row[$mode . '_avatar'])); 1285 return true; 1286 } 1287 1288 return false; 1289 } 1290 1291 /** 1292 * Remote avatar linkage 1293 */ 1294 function avatar_remote($data, &$error) 1295 { 1296 global $config, $db, $user, $phpbb_root_path, $phpEx; 1297 1298 if (!preg_match('#^(http|https|ftp)://#i', $data['remotelink'])) 1299 { 1300 $data['remotelink'] = 'http://' . $data['remotelink']; 1301 } 1302 1303 if (!preg_match('#^(http|https|ftp)://(.*?\.)*?[a-z0-9\-]+?\.[a-z]{2,4}:?([0-9]*?).*?\.(gif|jpg|jpeg|png)$#i', $data['remotelink'])) 1304 { 1305 $error[] = $user->lang['AVATAR_URL_INVALID']; 1306 return false; 1307 } 1308 1309 // Make sure getimagesize works... 1310 if (($image_data = @getimagesize($data['remotelink'])) === false) 1311 { 1312 $error[] = $user->lang['UNABLE_GET_IMAGE_SIZE']; 1313 return false; 1314 } 1315 1316 $width = ($data['width'] && $data['height']) ? $data['width'] : $image_data[0]; 1317 $height = ($data['width'] && $data['height']) ? $data['height'] : $image_data[1]; 1318 1319 if (!$width || !$height) 1320 { 1321 $error[] = $user->lang['AVATAR_NO_SIZE']; 1322 return false; 1323 } 1324 1325 // Check image type 1326 include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx); 1327 $types = fileupload::image_types(); 1328 $extension = strtolower(filespec::get_extension($data['remotelink'])); 1329 1330 if (!isset($types[$image_data[2]]) || !in_array($extension, $types[$image_data[2]])) 1331 { 1332 if (!isset($types[$image_data[2]])) 1333 { 1334 $error[] = $user->lang['UNABLE_GET_IMAGE_SIZE']; 1335 } 1336 else 1337 { 1338 $error[] = sprintf($user->lang['IMAGE_FILETYPE_MISMATCH'], $types[$image_data[2]][0], $extension); 1339 } 1340 return false; 1341 } 1342 1343 if ($config['avatar_max_width'] || $config['avatar_max_height']) 1344 { 1345 if ($width > $config['avatar_max_width'] || $height > $config['avatar_max_height']) 1346 { 1347 $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height); 1348 return false; 1349 } 1350 } 1351 1352 if ($config['avatar_min_width'] || $config['avatar_min_height']) 1353 { 1354 if ($width < $config['avatar_min_width'] || $height < $config['avatar_min_height']) 1355 { 1356 $error[] = sprintf($user->lang['AVATAR_WRONG_SIZE'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height'], $width, $height); 1357 return false; 1358 } 1359 } 1360 1361 return array(AVATAR_REMOTE, $data['remotelink'], $width, $height); 1362 } 1363 1364 /** 1365 * Avatar upload using the upload class 1366 */ 1367 function avatar_upload($data, &$error) 1368 { 1369 global $phpbb_root_path, $config, $db, $user, $phpEx; 1370 1371 // Init upload class 1372 include_once($phpbb_root_path . 'includes/functions_upload.' . $phpEx); 1373 $upload = new fileupload('AVATAR_', array('jpg', 'jpeg', 'gif', 'png'), $config['avatar_filesize'], $config['avatar_min_width'], $config['avatar_min_height'], $config['avatar_max_width'], $config['avatar_max_height']); 1374 1375 if (!empty($_FILES['uploadfile']['name'])) 1376 { 1377 $file = $upload->form_upload('uploadfile'); 1378 } 1379 else 1380 { 1381 $file = $upload->remote_upload($data['uploadurl']); 1382 } 1383 1384 $file->clean_filename('real', $data['user_id'] . '_'); 1385 1386 $destination = $config['avatar_path']; 1387 1388 if ($destination{(sizeof($destination)-1)} == '/' || $destination{(sizeof($destination)-1)} == '\\') 1389 { 1390 $destination = substr($destination, 0, sizeof($destination)-2); 1391 } 1392 1393 $destination = str_replace(array('../', '..\\', './', '.\\'), '', $destination); 1394 if ($destination && ($destination[0] == '/' || $destination[0] == "\\")) 1395 { 1396 $destination = ''; 1397 } 1398 1399 $file->move_file($destination); 1400 1401 if (sizeof($file->error)) 1402 { 1403 $file->remove(); 1404 $error = array_merge($error, $file->error); 1405 } 1406 1407 return array(AVATAR_UPLOAD, $file->get('realname'), $file->get('width'), $file->get('height')); 1408 } 1409 1410 /** 1411 * Avatar Gallery 1412 */ 1413 function avatar_gallery($category, $avatar_select, $items_per_column, $block_var = 'avatar_row') 1414 { 1415 global $user, $cache, $template; 1416 global $config, $phpbb_root_path; 1417 1418 $avatar_list = array(); 1419 1420 $path = $phpbb_root_path . $config['avatar_gallery_path']; 1421 1422 if (!file_exists($path) || !is_dir($path)) 1423 { 1424 $avatar_list = array($user->lang['NO_AVATAR_CATEGORY'] => array()); 1425 } 1426 else 1427 { 1428 // Collect images 1429 $dp = @opendir($path); 1430 1431 while (($file = readdir($dp)) !== false) 1432 { 1433 if ($file[0] != '.' && is_dir("$path/$file")) 1434 { 1435 $avatar_row_count = $avatar_col_count = 0; 1436 1437 $dp2 = @opendir("$path/$file"); 1438 while (($sub_file = readdir($dp2)) !== false) 1439 { 1440 if (preg_match('#\.(?:gif|png|jpe?g)$#i', $sub_file)) 1441 { 1442 $avatar_list[$file][$avatar_row_count][$avatar_col_count] = array( 1443 'file' => "$file/$sub_file", 1444 'filename' => $sub_file, 1445 'name' => ucfirst(str_replace('_', ' ', preg_replace('#^(.*)\..*$#', '\1', $sub_file))), 1446 ); 1447 1448 $avatar_col_count++; 1449 if ($avatar_col_count == $items_per_column) 1450 { 1451 $avatar_row_count++; 1452 $avatar_col_count = 0; 1453 } 1454 } 1455 } 1456 closedir($dp2); 1457 } 1458 } 1459 closedir($dp); 1460 } 1461 1462 if (!sizeof($avatar_list)) 1463 { 1464 $avatar_list = array($user->lang['NO_AVATAR_CATEGORY'] => array()); 1465 } 1466 1467 @ksort($avatar_list); 1468 1469 $category = (!$category) ? key($avatar_list) : $category; 1470 $avatar_categories = array_keys($avatar_list); 1471 1472 $s_category_options = ''; 1473 foreach ($avatar_categories as $cat) 1474 { 1475 $s_category_options .= '<option value="' . $cat . '"' . (($cat == $category) ? ' selected="selected"' : '') . '>' . $cat . '</option>'; 1476 } 1477 1478 $template->assign_vars(array( 1479 'S_IN_AVATAR_GALLERY' => true, 1480 'S_CAT_OPTIONS' => $s_category_options) 1481 ); 1482 1483 $avatar_list = $avatar_list[$category]; 1484 1485 foreach ($avatar_list as $avatar_row_ary) 1486 { 1487 $template->assign_block_vars($block_var, array()); 1488 1489 foreach ($avatar_row_ary as $avatar_col_ary) 1490 { 1491 $template->assign_block_vars($block_var . '.avatar_column', array( 1492 'AVATAR_IMAGE' => $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar_col_ary['file'], 1493 'AVATAR_NAME' => $avatar_col_ary['name'], 1494 'AVATAR_FILE' => $avatar_col_ary['filename']) 1495 ); 1496 1497 $template->assign_block_vars($block_var . '.avatar_option_column', array( 1498 'AVATAR_IMAGE' => $phpbb_root_path . $config['avatar_gallery_path'] . '/' . $avatar_col_ary['file'], 1499 'S_OPTIONS_AVATAR' => $avatar_col_ary['filename']) 1500 ); 1501 } 1502 } 1503 1504 return $avatar_list; 1505 } 1506 1507 // 1508 // Usergroup functions 1509 // 1510 1511 /** 1512 * Add or edit a group. If we're editing a group we only update user 1513 * parameters such as rank, etc. if they are changed 1514 */ 1515 function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow_desc_bbcode = false, $allow_desc_urls = false, $allow_desc_smilies = false) 1516 { 1517 global $phpbb_root_path, $config, $db, $user, $file_upload; 1518 1519 $error = array(); 1520 $attribute_ary = array( 1521 'group_colour' => 'string', 1522 'group_rank' => 'int', 1523 'group_avatar' => 'string', 1524 'group_avatar_type' => 'int', 1525 'group_avatar_width' => 'int', 1526 'group_avatar_height' => 'int', 1527 1528 'group_receive_pm' => 'int', 1529 'group_legend' => 'int', 1530 'group_message_limit' => 'int', 1531 ); 1532 1533 // Those are group-only attributes 1534 $group_only_ary = array('group_receive_pm', 'group_legend', 'group_message_limit'); 1535 1536 // Check data 1537 if (!utf8_strlen($name) || utf8_strlen($name) > 40) 1538 { 1539 $error[] = (!utf8_strlen($name)) ? $user->lang['GROUP_ERR_USERNAME'] : $user->lang['GROUP_ERR_USER_LONG']; 1540 } 1541 1542 if (utf8_strlen($desc) > 255) 1543 { 1544 $error[] = $user->lang['GROUP_ERR_DESC_LONG']; 1545 } 1546 1547 if (!in_array($type, array(GROUP_OPEN, GROUP_CLOSED, GROUP_HIDDEN, GROUP_SPECIAL, GROUP_FREE))) 1548 { 1549 $error[] = $user->lang['GROUP_ERR_TYPE']; 1550 } 1551 1552 if (!sizeof($error)) 1553 { 1554 $sql_ary = array( 1555 'group_name' => (string) $name, 1556 'group_desc' => (string) $desc, 1557 'group_desc_uid' => '', 1558 'group_desc_bitfield' => '', 1559 'group_type' => (int) $type, 1560 ); 1561 1562 // Parse description 1563 if ($desc) 1564 { 1565 generate_text_for_storage($sql_ary['group_desc'], $sql_ary['group_desc_uid'], $sql_ary['group_desc_bitfield'], $sql_ary['group_desc_options'], $allow_desc_bbcode, $allow_desc_urls, $allow_desc_smilies); 1566 } 1567 1568 if (sizeof($group_attributes)) 1569 { 1570 foreach ($attribute_ary as $attribute => $_type) 1571 { 1572 if (isset($group_attributes[$attribute])) 1573 { 1574 settype($group_attributes[$attribute], $_type); 1575 $sql_ary[$attribute] = $group_attributes[$attribute]; 1576 } 1577 } 1578 } 1579 1580 // Setting the log message before we set the group id (if group gets added) 1581 $log = ($group_id) ? 'LOG_GROUP_UPDATED' : 'LOG_GROUP_CREATED'; 1582 1583 $query = ''; 1584 1585 if ($group_id) 1586 { 1587 $sql = 'UPDATE ' . GROUPS_TABLE . ' 1588 SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " 1589 WHERE group_id = $group_id"; 1590 } 1591 else 1592 { 1593 $sql = 'INSERT INTO ' . GROUPS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); 1594 } 1595 $db->sql_query($sql); 1596 1597 if (!$group_id) 1598 { 1599 $group_id = $db->sql_nextid(); 1600 } 1601 1602 // Set user attributes 1603 $sql_ary = array(); 1604 if (sizeof($group_attributes)) 1605 { 1606 foreach ($attribute_ary as $attribute => $_type) 1607 { 1608 if (isset($group_attributes[$attribute]) && !in_array($attribute, $group_only_ary)) 1609 { 1610 // If we are about to set an avatar, we will not overwrite user avatars if no group avatar is set... 1611 if (strpos($attribute, 'group_avatar') === 0 && !$group_attributes[$attribute]) 1612 { 1613 continue; 1614 } 1615 1616 $sql_ary[$attribute] = $group_attributes[$attribute]; 1617 } 1618 } 1619 } 1620 1621 if (sizeof($sql_ary)) 1622 { 1623 $sql = 'SELECT user_id 1624 FROM ' . USERS_TABLE . ' 1625 WHERE group_id = ' . $group_id; 1626 $result = $db->sql_query($sql); 1627 1628 $user_ary = array(); 1629 while ($row = $db->sql_fetchrow($result)) 1630 { 1631 $user_ary[] = $row['user_id']; 1632 } 1633 1634 $db->sql_freeresult($result); 1635 1636 if (sizeof($user_ary)) 1637 { 1638 group_set_user_default($group_id, $user_ary, $sql_ary); 1639 } 1640 } 1641 1642 $name = ($type == GROUP_SPECIAL) ? $user->lang['G_' . $name] : $name; 1643 add_log('admin', $log, $name); 1644 } 1645 1646 return (sizeof($error)) ? $error : false; 1647 } 1648 1649 /** 1650 * Group Delete 1651 */ 1652 function group_delete($group_id, $group_name = false) 1653 { 1654 global $db, $phpbb_root_path, $phpEx; 1655 1656 if (!$group_name) 1657 { 1658 $group_name = get_group_name($group_id); 1659 } 1660 1661 $start = 0; 1662 1663 do 1664 { 1665 $user_id_ary = $username_ary = array(); 1666 1667 // Batch query for group members, call group_user_del 1668 $sql = 'SELECT u.user_id, u.username 1669 FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . " u 1670 WHERE ug.group_id = $group_id 1671 AND u.user_id = ug.user_id"; 1672 $result = $db->sql_query_limit($sql, 200, $start); 1673 1674 if ($row = $db->sql_fetchrow($result)) 1675 { 1676 do 1677 { 1678 $user_id_ary[] = $row['user_id']; 1679 $username_ary[] = $row['username']; 1680 1681 $start++; 1682 } 1683 while ($row = $db->sql_fetchrow($result)); 1684 1685 group_user_del($group_id, $user_id_ary, $username_ary, $group_name); 1686 } 1687 else 1688 { 1689 $start = 0; 1690 } 1691 $db->sql_freeresult($result); 1692 } 1693 while ($start); 1694 1695 // Delete group 1696 $sql = 'DELETE FROM ' . GROUPS_TABLE . " 1697 WHERE group_id = $group_id"; 1698 $db->sql_query($sql); 1699 1700 // Delete auth entries from the groups table 1701 $sql = 'DELETE FROM ' . ACL_GROUPS_TABLE . " 1702 WHERE group_id = $group_id"; 1703 $db->sql_query($sql); 1704 1705 // Re-cache moderators 1706 if (!function_exists('cache_moderators')) 1707 { 1708 include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); 1709 } 1710 1711 cache_moderators(); 1712 1713 add_log('admin', 'LOG_GROUP_DELETE', $group_name); 1714 1715 return 'GROUP_DELETED'; 1716 } 1717 1718 /** 1719 * Add user(s) to group 1720 * 1721 * @return false if no errors occurred, else the user lang string for the relevant error, for example 'NO_USER' 1722 */ 1723 function group_user_add($group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $default = false, $leader = 0, $pending = 0, $group_attributes = false) 1724 { 1725 global $db, $auth; 1726 1727 // We need both username and user_id info 1728 $result = user_get_id_name($user_id_ary, $username_ary); 1729 1730 if (!sizeof($user_id_ary) || $result !== false) 1731 { 1732 return 'NO_USER'; 1733 } 1734 1735 // Remove users who are already members of this group 1736 $sql = 'SELECT user_id, group_leader 1737 FROM ' . USER_GROUP_TABLE . ' 1738 WHERE ' . $db->sql_in_set('user_id', $user_id_ary) . " 1739 AND group_id = $group_id"; 1740 $result = $db->sql_query($sql); 1741 1742 $add_id_ary = $update_id_ary = array(); 1743 while ($row = $db->sql_fetchrow($result)) 1744 { 1745 $add_id_ary[] = (int) $row['user_id']; 1746 1747 if ($leader && !$row['group_leader']) 1748 { 1749 $update_id_ary[] = (int) $row['user_id']; 1750 } 1751 } 1752 $db->sql_freeresult($result); 1753 1754 // Do all the users exist in this group? 1755 $add_id_ary = array_diff($user_id_ary, $add_id_ary); 1756 1757 // If we have no users 1758 if (!sizeof($add_id_ary) && !sizeof($update_id_ary)) 1759 { 1760 return 'GROUP_USERS_EXIST'; 1761 } 1762 1763 $db->sql_transaction('begin'); 1764 1765 // Insert the new users 1766 if (sizeof($add_id_ary)) 1767 { 1768 $sql_ary = array(); 1769 1770 foreach ($add_id_ary as $user_id) 1771 { 1772 $sql_ary[] = array( 1773 'user_id' => $user_id, 1774 'group_id' => $group_id, 1775 'group_leader' => $leader, 1776 'user_pending' => $pending, 1777 ); 1778 } 1779 1780 $db->sql_multi_insert(USER_GROUP_TABLE, $sql_ary); 1781 } 1782 1783 if (sizeof($update_id_ary)) 1784 { 1785 $sql = 'UPDATE ' . USER_GROUP_TABLE . ' 1786 SET group_leader = 1 1787 WHERE ' . $db->sql_in_set('user_id', $update_id_ary) . " 1788 AND group_id = $group_id"; 1789 $db->sql_query($sql); 1790 } 1791 1792 if ($default) 1793 { 1794 group_set_user_default($group_id, $user_id_ary, $group_attributes); 1795 } 1796 1797 $db->sql_transaction('commit'); 1798 1799 // Clear permissions cache of relevant users 1800 $auth->acl_clear_prefetch($user_id_ary); 1801 1802 if (!$group_name) 1803 { 1804 $group_name = get_group_name($group_id); 1805 } 1806 1807 $log = ($leader) ? 'LOG_MODS_ADDED' : 'LOG_USERS_ADDED'; 1808 1809 add_log('admin', $log, $group_name, implode(', ', $username_ary)); 1810 1811 group_update_listings($group_id); 1812 1813 // Return false - no error 1814 return false; 1815 } 1816 1817 /** 1818 * Remove a user/s from a given group. When we remove users we update their 1819 * default group_id. We do this by examining which "special" groups they belong 1820 * to. The selection is made based on a reasonable priority system 1821 * 1822 * @return false if no errors occurred, else the user lang string for the relevant error, for example 'NO_USER' 1823 */ 1824 function group_user_del($group_id, $user_id_ary = false, $username_ary = false, $group_name = false) 1825 { 1826 global $db, $auth; 1827 1828 $group_order = array('ADMINISTRATORS', 'GLOBAL_MODERATORS', 'REGISTERED_COPPA', 'REGISTERED', 'BOTS', 'GUESTS'); 1829 1830 // We need both username and user_id info 1831 $result = user_get_id_name($user_id_ary, $username_ary); 1832 1833 if (!sizeof($user_id_ary) || $result !== false) 1834 { 1835 return 'NO_USER'; 1836 } 1837 1838 $sql = 'SELECT * 1839 FROM ' . GROUPS_TABLE . ' 1840 WHERE ' . $db->sql_in_set('group_name', $group_order); 1841 $result = $db->sql_query($sql); 1842 1843 $group_order_id = $special_group_data = array(); 1844 while ($row = $db->sql_fetchrow($result)) 1845 { 1846 $group_order_id[$row['group_name']] = $row['group_id']; 1847 1848 $special_group_data[$row['group_id']] = array( 1849 'group_colour' => $row['group_colour'], 1850 'group_rank' => $row['group_rank'], 1851 ); 1852 1853 // Only set the group avatar if one is defined... 1854 if ($row['group_avatar']) 1855 { 1856 $special_group_data[$row['group_id']] = array_merge($special_group_data[$row['group_id']], array( 1857 'group_avatar' => $row['group_avatar'], 1858 'group_avatar_type' => $row['group_avatar_type'], 1859 'group_avatar_width' => $row['group_avatar_width'], 1860 'group_avatar_height' => $row['group_avatar_height']) 1861 ); 1862 } 1863 } 1864 $db->sql_freeresult($result); 1865 1866 // Get users default groups - we only need to reset default group membership if the group from which the user gets removed is set as default 1867 $sql = 'SELECT user_id, group_id 1868 FROM ' . USERS_TABLE . ' 1869 WHERE ' . $db->sql_in_set('user_id', $user_id_ary); 1870 $result = $db->sql_query($sql); 1871 1872 $default_groups = array(); 1873 while ($row = $db->sql_fetchrow($result)) 1874 { 1875 $default_groups[$row['user_id']] = $row['group_id']; 1876 } 1877 $db->sql_freeresult($result); 1878 1879 // What special group memberships exist for these users? 1880 $sql = 'SELECT g.group_id, g.group_name, ug.user_id 1881 FROM ' . USER_GROUP_TABLE . ' ug, ' . GROUPS_TABLE . ' g 1882 WHERE ' . $db->sql_in_set('ug.user_id', $user_id_ary) . " 1883 AND g.group_id = ug.group_id 1884 AND g.group_id <> $group_id 1885 AND g.group_type = " . GROUP_SPECIAL . ' 1886 ORDER BY ug.user_id, g.group_id'; 1887 $result = $db->sql_query($sql); 1888 1889 $temp_ary = array(); 1890 while ($row = $db->sql_fetchrow($result)) 1891 { 1892 if ($default_groups[$row['user_id']] == $group_id && (!isset($temp_ary[$row['user_id']]) || array_search($row['group_name'], $group_order) < $temp_ary[$row['user_id']])) 1893 { 1894 $temp_ary[$row['user_id']] = $row['group_id']; 1895 } 1896 } 1897 $db->sql_freeresult($result); 1898 1899 $sql_where_ary = array(); 1900 foreach ($temp_ary as $uid => $gid) 1901 { 1902 $sql_where_ary[$gid][] = $uid; 1903 } 1904 unset($temp_ary); 1905 1906 foreach ($special_group_data as $gid => $default_data_ary) 1907 { 1908 if (isset($sql_where_ary[$gid]) && sizeof($sql_where_ary[$gid])) 1909 { 1910 group_set_user_default($gid, $sql_where_ary[$gid], $special_group_data[$gid]); 1911 } 1912 } 1913 unset($special_group_data); 1914 1915 $sql = 'DELETE FROM ' . USER_GROUP_TABLE . " 1916 WHERE group_id = $group_id 1917 AND " . $db->sql_in_set('user_id', $user_id_ary); 1918 $db->sql_query($sql); 1919 1920 // Clear permissions cache of relevant users 1921 $auth->acl_clear_prefetch($user_id_ary); 1922 1923 if (!$group_name) 1924 { 1925 $group_name = get_group_name($group_id); 1926 } 1927 1928 $log = 'LOG_GROUP_REMOVE'; 1929 1930 add_log('admin', $log, $group_name, implode(', ', $username_ary)); 1931 1932 // Return false - no error 1933 return false; 1934 } 1935 1936 /** 1937 * This is used to promote (to leader), demote or set as default a member/s 1938 */ 1939 function group_user_attributes($action, $group_id, $user_id_ary = false, $username_ary = false, $group_name = false, $group_attributes = false) 1940 { 1941 global $db, $auth, $phpbb_root_path, $phpEx, $config; 1942 1943 // We need both username and user_id info 1944 $result = user_get_id_name($user_id_ary, $username_ary); 1945 1946 if (!sizeof($user_id_ary) || $result !== false) 1947 { 1948 return false; 1949 } 1950 1951 if (!$group_name) 1952 { 1953 $group_name = get_group_name($group_id); 1954 } 1955 1956 switch ($action) 1957 { 1958 case 'demote': 1959 case 'promote': 1960 $sql = 'UPDATE ' . USER_GROUP_TABLE . ' 1961 SET group_leader = ' . (($action == 'promote') ? 1 : 0) . " 1962 WHERE group_id = $group_id 1963 AND " . $db->sql_in_set('user_id', $user_id_ary); 1964 $db->sql_query($sql); 1965 1966 $log = ($action == 'promote') ? 'LOG_GROUP_PROMOTED' : 'LOG_GROUP_DEMOTED'; 1967 break; 1968 1969 case 'approve': 1970 // Make sure we only approve those which are pending ;) 1971 $sql = 'SELECT u.user_id, u.user_email, u.username, u.user_notify_type, u.user_jabber, u.user_lang 1972 FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug 1973 WHERE ug.group_id = ' . $group_id . ' 1974 AND ug.user_pending = 1 1975 AND ug.user_id = u.user_id 1976 AND ' . $db->sql_in_set('ug.user_id', $user_id_ary); 1977 $result = $db->sql_query($sql); 1978 1979 $user_id_ary = $email_users = array(); 1980 while ($row = $db->sql_fetchrow($result)) 1981 { 1982 $user_id_ary[] = $row['user_id']; 1983 $email_users[] = $row; 1984 } 1985 $db->sql_freeresult($result); 1986 1987 if (!sizeof($user_id_ary)) 1988 { 1989 return false; 1990 } 1991 1992 $sql = 'UPDATE ' . USER_GROUP_TABLE . " 1993 SET user_pending = 0 1994 WHERE group_id = $group_id 1995 AND " . $db->sql_in_set('user_id', $user_id_ary); 1996 $db->sql_query($sql); 1997 1998 // Send approved email to users... 1999 include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); 2000 $messenger = new messenger(); 2001 2002 foreach ($email_users as $row) 2003 { 2004 $messenger->template('group_approved', $row['user_lang']); 2005 2006 $messenger->replyto($config['board_email']); 2007 $messenger->to($row['user_email'], $row['username']); 2008 $messenger->im($row['user_jabber'], $row['username']); 2009 2010 $messenger->assign_vars(array( 2011 'USERNAME' => htmlspecialchars_decode($row['username']), 2012 'GROUP_NAME' => htmlspecialchars_decode($group_name), 2013 'U_GROUP' => generate_board_url() . "/ucp.$phpEx?i=groups&mode=membership") 2014 ); 2015 2016 $messenger->send($row['user_notify_type']); 2017 $messenger->reset(); 2018 } 2019 2020 $messenger->save_queue(); 2021 2022 $log = 'LOG_USERS_APPROVED'; 2023 break; 2024 2025 case 'default': 2026 group_set_user_default($group_id, $user_id_ary, $group_attributes); 2027 $log = 'LOG_GROUP_DEFAULTS'; 2028 break; 2029 } 2030 2031 // Clear permissions cache of relevant users 2032 $auth->acl_clear_prefetch($user_id_ary); 2033 2034 add_log('admin', $log, $group_name, implode(', ', $username_ary)); 2035 2036 return true; 2037 } 2038 2039 /** 2040 * Set users default group 2041 */ 2042 function group_set_user_default($group_id, $user_id_ary, $group_attributes = false) 2043 { 2044 global $db; 2045 2046 if (empty($user_id_ary)) 2047 { 2048 return; 2049 } 2050 2051 $attribute_ary = array( 2052 'group_colour' => 'string', 2053 'group_rank' => 'int', 2054 'group_avatar' => 'string', 2055 'group_avatar_type' => 'int', 2056 'group_avatar_width' => 'int', 2057 'group_avatar_height' => 'int', 2058 ); 2059 2060 $sql_ary = array( 2061 'group_id' => $group_id 2062 ); 2063 2064 // Were group attributes passed to the function? If not we need to obtain them 2065 if ($group_attributes === false) 2066 { 2067 $sql = 'SELECT ' . implode(', ', array_keys($attribute_ary)) . ' 2068 FROM ' . GROUPS_TABLE . " 2069 WHERE group_id = $group_id"; 2070 $result = $db->sql_query($sql); 2071 $group_attributes = $db->sql_fetchrow($result); 2072 $db->sql_freeresult($result); 2073 } 2074 2075 foreach ($attribute_ary as $attribute => $type) 2076 { 2077 if (isset($group_attributes[$attribute])) 2078 { 2079 // If we are about to set an avatar, we will not overwrite user avatars if no group avatar is set... 2080 if (strpos($attribute, 'group_avatar') === 0 && !$group_attributes[$attribute]) 2081 { 2082 continue; 2083 } 2084 2085 settype($group_attributes[$attribute], $type); 2086 $sql_ary[str_replace('group_', 'user_', $attribute)] = $group_attributes[$attribute]; 2087 } 2088 } 2089 2090 // Before we update the user attributes, we will make a list of those having now the group avatar assigned 2091 if (in_array('user_avatar', array_keys($sql_ary))) 2092 { 2093 // Ok, get the original avatar data from users having an uploaded one (we need to remove these from the filesystem) 2094 $sql = 'SELECT user_id, group_id, user_avatar 2095 FROM ' . USERS_TABLE . ' 2096 WHERE ' . $db->sql_in_set('user_id', $user_id_ary) . ' 2097 AND user_avatar_type = ' . AVATAR_UPLOAD; 2098 $result = $db->sql_query($sql); 2099 2100 while ($row = $db->sql_fetchrow($result)) 2101 { 2102 avatar_delete('user', $row); 2103 } 2104 $db->sql_freeresult($result); 2105 } 2106 2107 $sql = 'UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' 2108 WHERE ' . $db->sql_in_set('user_id', $user_id_ary); 2109 $db->sql_query($sql); 2110 2111 if (in_array('user_colour', array_keys($sql_ary))) 2112 { 2113 // Update any cached colour information for these users 2114 $sql = 'UPDATE ' . FORUMS_TABLE . " SET forum_last_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "' 2115 WHERE " . $db->sql_in_set('forum_last_poster_id', $user_id_ary); 2116 $db->sql_query($sql); 2117 2118 $sql = 'UPDATE ' . TOPICS_TABLE . " SET topic_first_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "' 2119 WHERE " . $db->sql_in_set('topic_poster', $user_id_ary); 2120 $db->sql_query($sql); 2121 2122 $sql = 'UPDATE ' . TOPICS_TABLE . " SET topic_last_poster_colour = '" . $db->sql_escape($sql_ary['user_colour']) . "' 2123 WHERE " . $db->sql_in_set('topic_last_poster_id', $user_id_ary); 2124 $db->sql_query($sql); 2125 } 2126 } 2127 2128 /** 2129 * Get group name 2130 */ 2131 function get_group_name($group_id) 2132 { 2133 global $db, $user; 2134 2135 $sql = 'SELECT group_name, group_type 2136 FROM ' . GROUPS_TABLE . ' 2137 WHERE group_id = ' . (int) $group_id; 2138 $result = $db->sql_query($sql); 2139 $row = $db->sql_fetchrow($result); 2140 $db->sql_freeresult($result); 2141 2142 if (!$row) 2143 { 2144 return ''; 2145 } 2146 2147 return ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name']; 2148 } 2149 2150 /** 2151 * Obtain either the members of a specified group, the groups the specified user is subscribed to 2152 * or checking if a specified user is in a specified group 2153 * 2154 * Note: Never use this more than once... first group your users/groups 2155 */ 2156 function group_memberships($group_id_ary = false, $user_id_ary = false, $return_bool = false) 2157 { 2158 global $db; 2159 2160 if (!$group_id_ary && !$user_id_ary) 2161 { 2162 return true; 2163 } 2164 2165 if ($user_id_ary) 2166 { 2167 $user_id_ary = (!is_array($user_id_ary)) ? array($user_id_ary) : $user_id_ary; 2168 } 2169 2170 if ($group_id_ary) 2171 { 2172 $group_id_ary = (!is_array($group_id_ary)) ? array($group_id_ary) : $group_id_ary; 2173 } 2174 2175 $sql = 'SELECT ug.*, u.username, u.user_email 2176 FROM ' . USER_GROUP_TABLE . ' ug, ' . USERS_TABLE . ' u 2177 WHERE ug.user_id = u.user_id AND '; 2178 2179 if ($group_id_ary) 2180 { 2181 $sql .= ' ' . $db->sql_in_set('ug.group_id', $group_id_ary); 2182 } 2183 2184 if ($user_id_ary) 2185 { 2186 $sql .= ($group_id_ary) ? ' AND ' : ' '; 2187 $sql .= $db->sql_in_set('ug.user_id', $user_id_ary); 2188 } 2189 2190 $result = ($return_bool) ? $db->sql_query_limit($sql, 1) : $db->sql_query($sql); 2191 2192 $row = $db->sql_fetchrow($result); 2193 2194 if ($return_bool) 2195 { 2196 $db->sql_freeresult($result); 2197 return ($row) ? true : false; 2198 } 2199 2200 if (!$row) 2201 { 2202 return false; 2203 } 2204 2205 $return = array(); 2206 2207 do 2208 { 2209 $return[] = $row; 2210 } 2211 while ($row = $db->sql_fetchrow($result)); 2212 2213 $db->sql_freeresult($result); 2214 2215 return $return; 2216 } 2217 2218 /** 2219 * Re-cache moderators and foes if group has a_ or m_ permissions 2220 */ 2221 function group_update_listings($group_id) 2222 { 2223 global $auth; 2224 2225 $hold_ary = $auth->acl_group_raw_data($group_id, array('a_', 'm_')); 2226 2227 if (!sizeof($hold_ary)) 2228 { 2229 return; 2230 } 2231 2232 $mod_permissions = $admin_permissions = false; 2233 2234 foreach ($hold_ary as $g_id => $forum_ary) 2235 { 2236 foreach ($forum_ary as $forum_id => $auth_ary) 2237 { 2238 foreach ($auth_ary as $auth_option => $setting) 2239 { 2240 if ($mod_permissions && $admin_permissions) 2241 { 2242 break 3; 2243 } 2244 2245 if ($setting != ACL_YES) 2246 { 2247 continue; 2248 } 2249 2250 if ($auth_option == 'm_') 2251 { 2252 $mod_permissions = true; 2253 } 2254 2255 if ($auth_option == 'a_') 2256 { 2257 $admin_permissions = true; 2258 } 2259 } 2260 } 2261 } 2262 2263 if ($mod_permissions) 2264 { 2265 if (!function_exists('cache_moderators')) 2266 { 2267 include($phpbb_root_path . 'includes/functions_admin.' . $phpEx); 2268 } 2269 cache_moderators(); 2270 } 2271 2272 if ($mod_permissions || $admin_permissions) 2273 { 2274 update_foes(); 2275 } 2276 } 2277 2278 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 22 00:35:05 2006 | Cross-referenced by PHPXref 0.6 |