| [ Index ] |
PHP Cross Reference of MyBB 1.6.5 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MyBB 1.6 4 * Copyright 2010 MyBB Group, All Rights Reserved 5 * 6 * Website: http://mybb.com 7 * License: http://mybb.com/about/license 8 * 9 * $Id: functions.php 5544 2011-08-08 15:41:40Z Tomm $ 10 */ 11 12 /** 13 * Logs an administrator action taking any arguments as log data. 14 */ 15 function log_admin_action() 16 { 17 global $db, $mybb; 18 19 $data = func_get_args(); 20 21 if(count($data) == 1 && is_array($data[0])) 22 { 23 $data = $data[0]; 24 } 25 26 if(!is_array($data)) 27 { 28 $data = array($data); 29 } 30 31 $log_entry = array( 32 "uid" => $mybb->user['uid'], 33 "ipaddress" => $db->escape_string(get_ip()), 34 "dateline" => TIME_NOW, 35 "module" => $db->escape_string($mybb->input['module']), 36 "action" => $db->escape_string($mybb->input['action']), 37 "data" => $db->escape_string(@serialize($data)) 38 ); 39 40 $db->insert_query("adminlog", $log_entry); 41 } 42 43 /** 44 * Redirects the current user to a specified URL. 45 * 46 * @param string The URL to redirect to 47 */ 48 function admin_redirect($url) 49 { 50 if(!headers_sent()) 51 { 52 $url = str_replace("&", "&", $url); 53 header("Location: $url"); 54 } 55 else 56 { 57 echo "<meta http-equiv=\"refresh\" content=\"0; url={$url}\">"; 58 } 59 exit; 60 } 61 62 /** 63 * Updates an administration session data array. 64 * 65 * @param string The name of the item in the data session to update 66 * @param mixed The value 67 */ 68 function update_admin_session($name, $value) 69 { 70 global $db, $admin_session; 71 72 $admin_session['data'][$name] = $value; 73 $updated_session = array( 74 "data" => $db->escape_string(@serialize($admin_session['data'])) 75 ); 76 $db->update_query("adminsessions", $updated_session, "sid='{$admin_session['sid']}'"); 77 } 78 79 /** 80 * Saves a "flash message" for the current user to be shown on their next page visit. 81 * 82 * @param string The message to show 83 * @param string The type of message to be shown (success|error) 84 */ 85 function flash_message($message, $type='') 86 { 87 $flash = array('message' => $message, 'type' => $type); 88 update_admin_session('flash_message', $flash); 89 } 90 91 /** 92 * Draw pagination for pages in the Admin CP. 93 * 94 * @param int The current page we're on 95 * @param int The number of items per page 96 * @param int The total number of items in this collection 97 * @param string The URL for pagination of this collection 98 * @return string The built pagination 99 */ 100 function draw_admin_pagination($page, $per_page, $total_items, $url) 101 { 102 global $mybb, $lang; 103 104 if($total_items <= $per_page) 105 { 106 return; 107 } 108 109 $pages = ceil($total_items / $per_page); 110 111 $pagination = "<div class=\"pagination\"><span class=\"pages\">{$lang->pages}: </span>\n"; 112 113 if($page > 1) 114 { 115 $prev = $page-1; 116 $prev_page = fetch_page_url($url, $prev); 117 $pagination .= "<a href=\"{$prev_page}\" class=\"pagination_previous\">« {$lang->previous}</a> \n"; 118 } 119 120 // Maximum number of "page bits" to show 121 if(!$mybb->settings['maxmultipagelinks']) 122 { 123 $mybb->settings['maxmultipagelinks'] = 5; 124 } 125 126 $max_links = $mybb->settings['maxmultipagelinks']; 127 128 $from = $page-floor($mybb->settings['maxmultipagelinks']/2); 129 $to = $page+floor($mybb->settings['maxmultipagelinks']/2); 130 131 if($from <= 0) 132 { 133 $from = 1; 134 $to = $from+$max_links-1; 135 } 136 137 if($to > $pages) 138 { 139 $to = $pages; 140 $from = $pages-$max_links+1; 141 if($from <= 0) 142 { 143 $from = 1; 144 } 145 } 146 147 if($to == 0) 148 { 149 $to = $pages; 150 } 151 152 153 if($from > 2) 154 { 155 $first = fetch_page_url($url, 1); 156 $pagination .= "<a href=\"{$first}\" title=\"Page 1\" class=\"pagination_first\">1</a> ... "; 157 } 158 159 for($i = $from; $i <= $to; ++$i) 160 { 161 $page_url = fetch_page_url($url, $i); 162 if($page == $i) 163 { 164 $pagination .= "<span class=\"pagination_current\">{$i}</span> \n"; 165 } 166 else 167 { 168 $pagination .= "<a href=\"{$page_url}\" title=\"{$lang->page} {$i}\">{$i}</a> \n"; 169 } 170 } 171 172 if($to < $pages) 173 { 174 $last = fetch_page_url($url, $pages); 175 $pagination .= "... <a href=\"{$last}\" title=\"{$lang->page} {$pages}\" class=\"pagination_last\">{$pages}</a>"; 176 } 177 178 if($page < $pages) 179 { 180 $next = $page+1; 181 $next_page = fetch_page_url($url, $next); 182 $pagination .= " <a href=\"{$next_page}\" class=\"pagination_next\">{$lang->next} »</a>\n"; 183 } 184 $pagination .= "</div>\n"; 185 return $pagination; 186 } 187 188 /** 189 * Builds a CSV parent list for a particular forum. 190 * 191 * @param int The forum ID 192 * @param string Optional separator - defaults to comma for CSV list 193 * @return string The built parent list 194 */ 195 function make_parent_list($fid, $navsep=",") 196 { 197 global $pforumcache, $db; 198 199 if(!$pforumcache) 200 { 201 $query = $db->simple_select("forums", "name, fid, pid", "", array("order_by" => "disporder, pid")); 202 while($forum = $db->fetch_array($query)) 203 { 204 $pforumcache[$forum['fid']][$forum['pid']] = $forum; 205 } 206 } 207 208 reset($pforumcache); 209 reset($pforumcache[$fid]); 210 211 foreach($pforumcache[$fid] as $key => $forum) 212 { 213 if($fid == $forum['fid']) 214 { 215 if($pforumcache[$forum['pid']]) 216 { 217 $navigation = make_parent_list($forum['pid'], $navsep).$navigation; 218 } 219 220 if($navigation) 221 { 222 $navigation .= $navsep; 223 } 224 $navigation .= $forum['fid']; 225 } 226 } 227 return $navigation; 228 } 229 230 function save_quick_perms($fid) 231 { 232 global $db, $inherit, $canview, $canpostthreads, $canpostreplies, $canpostpolls, $canpostattachments, $cache; 233 234 $permission_fields = array(); 235 236 $field_list = $db->show_fields_from("forumpermissions"); 237 foreach($field_list as $field) 238 { 239 if(strpos($field['Field'], 'can') !== false) 240 { 241 $permission_fields[$field['Field']] = 1; 242 } 243 } 244 245 // "Can Only View Own Threads" permission is a forum permission only option 246 $usergroup_permission_fields = $permission_fields; 247 unset($usergroup_permission_fields['canonlyviewownthreads']); 248 249 $query = $db->simple_select("usergroups", "gid"); 250 while($usergroup = $db->fetch_array($query)) 251 { 252 $query2 = $db->simple_select("forumpermissions", $db->escape_string(implode(',', array_keys($permission_fields))), "fid='{$fid}' AND gid='{$usergroup['gid']}'", array('limit' => 1)); 253 $existing_permissions = $db->fetch_array($query2); 254 255 if(!$existing_permissions) 256 { 257 $query2 = $db->simple_select("usergroups", $db->escape_string(implode(',', array_keys($usergroup_permission_fields))), "gid='{$usergroup['gid']}'", array('limit' => 1)); 258 $existing_permissions = $db->fetch_array($query2); 259 } 260 261 // Delete existing permissions 262 $db->delete_query("forumpermissions", "fid='{$fid}' AND gid='{$usergroup['gid']}'"); 263 264 // Only insert the new ones if we're using custom permissions 265 if($inherit[$usergroup['gid']] != 1) 266 { 267 if($canview[$usergroup['gid']] == 1) 268 { 269 $pview = 1; 270 } 271 else 272 { 273 $pview = 0; 274 } 275 276 if($canpostthreads[$usergroup['gid']] == 1) 277 { 278 $pthreads = 1; 279 } 280 else 281 { 282 $pthreads = 0; 283 } 284 285 if($canpostreplies[$usergroup['gid']] == 1) 286 { 287 $preplies = 1; 288 } 289 else 290 { 291 $preplies = 0; 292 } 293 294 if($canpostpolls[$usergroup['gid']] == 1) 295 { 296 $ppolls = 1; 297 } 298 else 299 { 300 $ppolls = 0; 301 } 302 303 if($canpostattachments[$usergroup['gid']] == 1) 304 { 305 $pattachments = 1; 306 } 307 else 308 { 309 $pattachments = 0; 310 } 311 312 if(!$preplies && !$pthreads) 313 { 314 $ppost = 0; 315 } 316 else 317 { 318 $ppost = 1; 319 } 320 321 $insertquery = array( 322 "fid" => intval($fid), 323 "gid" => intval($usergroup['gid']), 324 "canview" => intval($pview), 325 "canpostthreads" => intval($pthreads), 326 "canpostreplys" => intval($preplies), 327 "canpostattachments" => intval($pattachments), 328 "canpostpolls" => intval($ppolls), 329 ); 330 331 foreach($permission_fields as $field => $value) 332 { 333 if(array_key_exists($field, $insertquery)) 334 { 335 continue; 336 } 337 338 $insertquery[$db->escape_string($field)] = intval($existing_permissions[$field]); 339 } 340 341 $db->insert_query("forumpermissions", $insertquery); 342 } 343 } 344 $cache->update_forumpermissions(); 345 } 346 347 /** 348 * Checks if a particular user has the necessary permissions to access a particular page. 349 * 350 * @param array Array containing module and action to check for 351 */ 352 function check_admin_permissions($action, $error = true) 353 { 354 global $mybb, $page, $lang, $modules_dir; 355 356 if(is_super_admin($mybb->user['uid'])) 357 { 358 return true; 359 } 360 361 require_once $modules_dir."/".$action['module']."/module_meta.php"; 362 if(function_exists($action['module']."_admin_permissions")) 363 { 364 $func = $action['module']."_admin_permissions"; 365 $permissions = $func(); 366 if($permissions['permissions'][$action['action']] && $mybb->admin['permissions'][$action['module']][$action['action']] != 1) 367 { 368 if($error) 369 { 370 $page->output_header($lang->access_denied); 371 $page->add_breadcrumb_item($lang->access_denied, "index.php?module=home-index"); 372 $page->output_error("<b>{$lang->access_denied}</b><ul><li style=\"list-style-type: none;\">{$lang->access_denied_desc}</li></ul>"); 373 $page->output_footer(); 374 exit; 375 } 376 else 377 { 378 return false; 379 } 380 } 381 } 382 383 return true; 384 } 385 386 /** 387 * Fetches the list of administrator permissions for a particular user or group 388 * 389 * @param int The user ID to fetch permissions for 390 * @param int The (optional) group ID to fetch permissions for 391 * @return array Array of permissions for specified user or group 392 */ 393 function get_admin_permissions($get_uid="", $get_gid="") 394 { 395 global $db, $mybb; 396 397 // Set UID and GID if none 398 $uid = $get_uid; 399 $gid = $get_gid; 400 401 $gid_array = array(); 402 403 if($uid === "") 404 { 405 $uid = $mybb->user['uid']; 406 } 407 408 if(!$gid) 409 { 410 // Prepare user's groups since the group isn't specified 411 $gid_array[] = (-1) * intval($mybb->user['usergroup']); 412 413 if($mybb->user['additionalgroups']) 414 { 415 $additional_groups = explode(',', $mybb->user['additionalgroups']); 416 417 if(!empty($additional_groups)) 418 { 419 // Make sure gids are negative 420 foreach($additional_groups as $g) 421 { 422 $gid_array[] = (-1) * abs($g); 423 } 424 } 425 } 426 } 427 else 428 { 429 // Group is specified 430 // Make sure gid is negative 431 $gid_array[] = (-1) * abs($gid); 432 } 433 434 // What are we trying to find? 435 if($get_gid && !$get_uid) 436 { 437 // A group only 438 439 $options = array( 440 "order_by" => "uid", 441 "order_dir" => "ASC", 442 "limit" => "1" 443 ); 444 $query = $db->simple_select("adminoptions", "permissions", "(uid='-{$get_gid}' OR uid='0') AND permissions != ''", $options); 445 return unserialize($db->fetch_field($query, "permissions")); 446 } 447 else 448 { 449 // A user and/or group 450 451 $options = array( 452 "order_by" => "uid", 453 "order_dir" => "DESC" 454 ); 455 456 // Prepare user's groups into SQL format 457 $group_sql = ''; 458 foreach($gid_array as $gid) 459 { 460 $group_sql .= " OR uid='{$gid}'"; 461 } 462 463 $perms_group = array(); 464 $query = $db->simple_select("adminoptions", "permissions, uid", "(uid='{$uid}'{$group_sql}) AND permissions != ''", $options); 465 while($perm = $db->fetch_array($query)) 466 { 467 $perm['permissions'] = unserialize($perm['permissions']); 468 469 // Sorting out which permission is which 470 if($perm['uid'] > 0) 471 { 472 $perms_user = $perm; 473 return $perms_user['permissions']; 474 } 475 elseif($perm['uid'] < 0) 476 { 477 $perms_group[] = $perm['permissions']; 478 } 479 else 480 { 481 $perms_def = $perm['permissions']; 482 } 483 } 484 485 // Figure out group permissions...ugh. 486 foreach($perms_group as $gperms) 487 { 488 if(!isset($final_group_perms)) 489 { 490 // Use this group as the base for admin group permissions 491 $final_group_perms = $gperms; 492 continue; 493 } 494 495 // Loop through each specific permission to find the highest permission 496 foreach($gperms as $perm_name => $perm_value) 497 { 498 if($final_group_perms[$perm_name] != '1' && $perm_value == '1') 499 { 500 $final_group_perms[$perm_name] = '1'; 501 } 502 } 503 } 504 505 // Send specific user, or group permissions before default. 506 // If user's permission are explicitly set, they've already been returned above. 507 if(isset($final_group_perms)) 508 { 509 return $final_group_perms; 510 } 511 else 512 { 513 return $perms_def; 514 } 515 } 516 } 517 518 /** 519 * Fetch the iconv/mb encoding for a particular MySQL encoding 520 * 521 * @param string The MySQL encoding 522 * @return string The iconv/mb encoding 523 */ 524 function fetch_iconv_encoding($mysql_encoding) 525 { 526 $mysql_encoding = explode("_", $mysql_encoding); 527 switch($mysql_encoding[0]) 528 { 529 case "utf8": 530 return "utf-8"; 531 break; 532 case "latin1": 533 return "iso-8859-1"; 534 break; 535 default: 536 return $mysql_encoding[0]; 537 } 538 } 539 540 /** 541 * Adds/Updates a Page/Tab to the permissions array in the adminoptions table 542 * 543 * @param string The name of the tab that is being affected 544 * @param string The name of the page being affected (optional - if not specified, will affect everything under the specified tab) 545 * @param integer Default permissions for the page (1 for allowed - 0 for disallowed - -1 to remove) 546 */ 547 function change_admin_permission($tab, $page="", $default=1) 548 { 549 global $db; 550 551 $query = $db->simple_select("adminoptions", "uid, permissions", "permissions != ''"); 552 while($adminoption = $db->fetch_array($query)) 553 { 554 $adminoption['permissions'] = unserialize($adminoption['permissions']); 555 556 if($default == -1) 557 { 558 if(!empty($page)) 559 { 560 unset($adminoption['permissions'][$tab][$page]); 561 } 562 else 563 { 564 unset($adminoption['permissions'][$tab]); 565 } 566 } 567 else 568 { 569 if(!empty($page)) 570 { 571 if($adminoption['uid'] == 0) 572 { 573 $adminoption['permissions'][$tab][$page] = 0; 574 } 575 else 576 { 577 $adminoption['permissions'][$tab][$page] = $default; 578 } 579 } 580 else 581 { 582 if($adminoption['uid'] == 0) 583 { 584 $adminoption['permissions'][$tab]['tab'] = 0; 585 } 586 else 587 { 588 $adminoption['permissions'][$tab]['tab'] = $default; 589 } 590 } 591 } 592 593 $db->update_query("adminoptions", array('permissions' => $db->escape_string(serialize($adminoption['permissions']))), "uid='{$adminoption['uid']}'"); 594 } 595 } 596 597 /** 598 * Checks if we have had too many attempts at logging into the ACP 599 * 600 * @param integer The uid of the admin to check 601 * @param boolean Return an array of the number of attempts and expiry time? (default false) 602 * @return mixed Return an array if the second parameter is true, boolean otherwise. 603 */ 604 function login_attempt_check_acp($uid=0, $return_num=false) 605 { 606 global $db, $mybb; 607 608 $attempts['loginattempts'] = 0; 609 610 if($uid > 0) 611 { 612 $query = $db->simple_select("adminoptions", "loginattempts, loginlockoutexpiry", "uid='".intval($uid)."'", 1); 613 $attempts = $db->fetch_array($query); 614 } 615 616 if($attempts['loginattempts'] <= 0) 617 { 618 return false; 619 } 620 621 if($mybb->settings['maxloginattempts'] > 0 && $attempts['loginattempts'] >= $mybb->settings['maxloginattempts']) 622 { 623 // Has the expiry dateline been set yet? 624 if($attempts['loginlockoutexpiry'] == 0 && $return_num == false) 625 { 626 $db->update_query("adminoptions", array("loginlockoutexpiry" => TIME_NOW+(intval($mybb->settings['loginattemptstimeout'])*60)), "uid='".intval($uid)."'", 1); 627 } 628 629 // Are we returning the # of login attempts? 630 if($return_num == true) 631 { 632 return $attempts; 633 } 634 // Otherwise are we still locked out? 635 else if($attempts['loginlockoutexpiry'] > TIME_NOW) 636 { 637 return true; 638 } 639 } 640 641 return false; 642 } 643 644 /** 645 * Checks whether there are any 'security' issues in templates via complex syntax 646 * 647 * @param string The template to be scanned 648 * @return boolean A true/false depending on if an issue was detected 649 */ 650 function check_template($template) 651 { 652 // Check to see if our database password is in the template 653 if(preg_match("#database'?\\s*\]\\s*\[\\s*'?password#", $template)) 654 { 655 return true; 656 } 657 658 // Any other malicious acts? 659 // Courtesy of ZiNgA BuRgA 660 if(preg_match("~\\{\\$.+?\\}~s", preg_replace('~\\{\\$+[a-zA-Z_][a-zA-Z_0-9]*((?:-\\>|\\:\\:)\\$*[a-zA-Z_][a-zA-Z_0-9]*|\\[\s*\\$*([\'"]?)[a-zA-Z_ 0-9 ]+\\2\\]\s*)*\\}~', '', $template))) 661 { 662 return true; 663 } 664 665 return false; 666 } 667 668 /** 669 * Provides a function to entirely delete a user's posts, and find the threads attached to them 670 * 671 * @param integer The uid of the user 672 * @param int A UNIX timestamp to delete posts that are older 673 * @return array An array of threads to delete, threads/forums to recount 674 */ 675 function delete_user_posts($uid, $date) 676 { 677 global $db, $cache; 678 $uid = intval($uid); 679 680 // Build an array of posts to delete 681 $postcache = array(); 682 $query = $db->simple_select("posts", "pid", "uid = '".$uid."' AND dateline < '".$date."'"); 683 while($post = $db->fetch_array($query)) 684 { 685 $postcache[] = $post['pid']; 686 } 687 688 if(!$db->num_rows($query)) 689 { 690 return false; 691 } 692 elseif(!empty($postcache)) 693 { 694 // Let's start deleting posts 695 $user_posts = implode(",", $postcache); 696 $query = $db->query(" 697 SELECT p.pid, p.visible, f.usepostcounts, t.tid AS thread, t.firstpost, t.fid AS forum 698 FROM ".TABLE_PREFIX."posts p 699 LEFT JOIN ".TABLE_PREFIX."forums f ON (f.fid=p.fid) 700 LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid) 701 WHERE p.pid IN ({$user_posts}) 702 "); 703 704 $post_count = 0; // Collect the post number to deduct from the user's postcount 705 $thread_list = array(); 706 $forum_list = array(); 707 $delete_thread_list = array(); 708 if(!$db->num_rows($query)) 709 { 710 return false; 711 } 712 else 713 { 714 while($post = $db->fetch_array($query)) 715 { 716 if($post['usepostcounts'] != 0 && $post['visible'] != 0) 717 { 718 ++$post_count; 719 } 720 721 if($post['pid'] == $post['firstpost']) 722 { 723 $delete_thread_list[] = $post['thread']; 724 } 725 726 if(!in_array($post['thread'], $thread_list) && !in_array($post['thread'], $delete_thread_list)) 727 { 728 $thread_list[] = $post['thread']; // Threads that have been affected by this action, that aren't marked to be deleted 729 } 730 if(!in_array($post['forum'], $forum_list)) 731 { 732 $forum_list[] = $post['forum']; // Forums that have been affected, too 733 } 734 735 // Remove the attachments to this post, then delete the post 736 remove_attachments($post['pid']); 737 $db->delete_query("posts", "pid = '".$post['pid']."'"); 738 $db->delete_query("pollvotes", "pid = '".$post['pid']."'"); // Delete pollvotes attached to this post 739 } 740 741 $db->update_query("users", array("postnum" => "postnum-".$post_count.""), "uid='".$uid."'", 1, true); 742 743 $to_return = array( 744 'to_delete' => $delete_thread_list, 745 'thread_update' => $thread_list, 746 'forum_update' => $forum_list 747 ); 748 749 return $to_return; 750 } 751 } 752 } 753 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Sun Dec 11 14:16:27 2011 | Cross-referenced by PHPXref 0.7.1 |