| [ Index ] |
PHP Cross Reference of MyBB 1.8.41 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MyBB 1.8 4 * Copyright 2014 MyBB Group, All Rights Reserved 5 * 6 * Website: http://www.mybb.com 7 * License: http://www.mybb.com/about/license 8 * 9 */ 10 11 // Disallow direct access to this file for security reasons 12 if(!defined("IN_MYBB")) 13 { 14 die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined."); 15 } 16 17 /** 18 * Login handling class, provides common structure to handle login events. 19 * 20 */ 21 class WarningsHandler extends DataHandler 22 { 23 /** 24 * The language file used in the data handler. 25 * 26 * @var string 27 */ 28 public $language_file = 'datahandler_warnings'; 29 30 /** 31 * The prefix for the language variables used in the data handler. 32 * 33 * @var string 34 */ 35 public $language_prefix = 'warnings'; 36 37 /** 38 * The stored data for the warning being written. 39 * 40 * @var array 41 */ 42 public $write_warning_data = array(); 43 44 /** 45 * The stored data for the warning being retrieved. 46 * 47 * @var array 48 */ 49 private $read_warning_data = array(); 50 51 /** 52 * Friendly redirect action after inserting a new warning. 53 * 54 * @var string 55 */ 56 public $friendly_action = ''; 57 58 /** 59 * Validate a warning user assets. 60 * 61 * @return boolean True when valid, false when invalid. 62 */ 63 function validate_user() 64 { 65 global $mybb; 66 67 $warning = &$this->data; 68 69 $user = get_user($warning['uid']); 70 71 if(!$user) 72 { 73 $this->set_error('error_invalid_user'); 74 return false; 75 } 76 77 if($user['uid'] == $mybb->user['uid']) 78 { 79 $this->set_error('error_cannot_warn_self'); 80 return false; 81 } 82 83 if($user['warningpoints'] >= $mybb->settings['maxwarningpoints']) 84 { 85 $this->set_error('error_user_reached_max_warning'); 86 return false; 87 } 88 89 return true; 90 } 91 92 /** 93 * Validate a warning post. 94 * 95 * @return boolean True when valid, false when invalid. 96 */ 97 function validate_post() 98 { 99 $warning = &$this->data; 100 101 $post = get_post($warning['pid']); 102 103 if(!$post) 104 { 105 $this->set_error('error_invalid_post'); 106 return false; 107 } 108 109 return true; 110 } 111 112 /** 113 * Validate a warning notes. 114 * 115 * @return boolean True when valid, false when invalid. 116 */ 117 function validate_notes() 118 { 119 $warning = &$this->data; 120 121 if(!trim($warning['notes'])) 122 { 123 $this->set_error('error_no_note'); 124 return false; 125 } 126 127 return true; 128 } 129 130 /** 131 * Validate maximum warnings per day for current user. 132 * 133 * @return boolean True when valid, false when invalid. 134 */ 135 function validate_maximum() 136 { 137 global $mybb, $db, $lang; 138 139 if($mybb->usergroup['maxwarningsday'] != 0) 140 { 141 $timecut = TIME_NOW-60*60*24; 142 $query = $db->simple_select("warnings", "COUNT(wid) AS given_today", "issuedby='{$mybb->user['uid']}' AND dateline>'$timecut'"); 143 $given_today = $db->fetch_field($query, "given_today"); 144 if($given_today >= $mybb->usergroup['maxwarningsday']) 145 { 146 $this->set_error('reached_max_warnings_day', array(my_number_format($mybb->usergroup['maxwarningsday']))); 147 return false; 148 } 149 } 150 151 return true; 152 } 153 154 /** 155 * Validate warnings type. 156 * 157 * @return boolean True when valid, false when invalid. 158 */ 159 function validate_type() 160 { 161 global $mybb, $db; 162 163 $warning = &$this->data; 164 165 // Issuing a custom warning 166 if($warning['type'] == 'custom') 167 { 168 if($mybb->settings['allowcustomwarnings'] == 0) 169 { 170 $this->set_error('error_cant_custom_warn'); 171 return false; 172 } 173 174 if(!$warning['custom_reason']) 175 { 176 $this->set_error('error_no_custom_reason'); 177 return false; 178 } 179 180 $warning['title'] = $warning['custom_reason']; 181 182 if(!$warning['custom_points'] || $warning['custom_points'] > $mybb->settings['maxwarningpoints'] || $warning['custom_points'] < 0) 183 { 184 $this->set_error('error_invalid_custom_points', array(my_number_format($mybb->settings['maxwarningpoints']))); 185 return false; 186 } 187 188 $warning['points'] = round($warning['custom_points']); 189 190 // Build expiry date 191 if($warning['expires_period'] == "hours") 192 { 193 $warning['expires'] = $warning['expires']*3600 + TIME_NOW; 194 } 195 else if($warning['expires_period'] == "days") 196 { 197 $warning['expires'] = $warning['expires']*86400 + TIME_NOW; 198 } 199 else if($warning['expires_period'] == "weeks") 200 { 201 $warning['expires'] = $warning['expires']*604800 + TIME_NOW; 202 } 203 else if($warning['expires_period'] == "months") 204 { 205 $warning['expires'] = $warning['expires']*2592000 + TIME_NOW; 206 } 207 else if($warning['expires_period'] == "never") 208 { 209 $warning['expires'] = 0; 210 } 211 else 212 { 213 // unkown expires_period 214 $this->set_error('error_invalid_expires_period'); 215 return false; 216 } 217 } 218 // Using a predefined warning type 219 else 220 { 221 $query = $db->simple_select("warningtypes", "*", "tid='".(int)$warning['type']."'"); 222 $this->warning_type = $db->fetch_array($query); 223 224 if(!$this->warning_type) 225 { 226 $this->set_error('error_invalid_type'); 227 return false; 228 } 229 230 $warning['points'] = $this->warning_type['points']; 231 $warning['title'] = ''; 232 $warning['expires'] = 0; 233 234 if($this->warning_type['expirationtime']) 235 { 236 $warning['expires'] = TIME_NOW+$this->warning_type['expirationtime']; 237 } 238 } 239 240 return true; 241 } 242 243 /** 244 * Validate a warning. 245 * 246 * @return boolean True when valid, false when invalid. 247 */ 248 function validate_warning() 249 { 250 global $plugins; 251 252 $warning = &$this->data; 253 254 // Verify all warning assets. 255 $this->validate_user(); 256 $this->validate_maximum(); 257 $this->validate_notes(); 258 259 if(array_key_exists('pid', $warning)) 260 { 261 $this->validate_post(); 262 } 263 if(array_key_exists('type', $warning)) 264 { 265 $this->validate_type(); 266 } 267 268 $plugins->run_hooks("datahandler_warnings_validate_warning", $this); 269 270 // We are done validating, return. 271 $this->set_validated(true); 272 273 if(count($this->get_errors()) > 0) 274 { 275 return false; 276 } 277 278 return true; 279 } 280 281 /** 282 * Gets a valid warning from the DB engine. 283 * 284 * @param int $wid 285 * @return array|bool array when valid, boolean false when invalid. 286 */ 287 function get($wid) 288 { 289 global $db; 290 291 $wid = (int)$wid; 292 if($wid <= 0) 293 { 294 return false; 295 } 296 297 $query = $db->simple_select("warnings", "*", "wid='".$wid."'"); 298 $this->read_warning_data = $db->fetch_array($query); 299 300 if(!$this->read_warning_data['wid']) 301 { 302 return false; 303 } 304 305 return $this->read_warning_data; 306 } 307 308 /** 309 * Expire old warnings in the database. 310 * 311 * @return boolean True when finished. 312 */ 313 function expire_warnings() 314 { 315 global $db; 316 317 $users = array(); 318 319 $query = $db->query(" 320 SELECT w.wid, w.uid, w.points, u.warningpoints 321 FROM ".TABLE_PREFIX."warnings w 322 LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=w.uid) 323 WHERE expires<".TIME_NOW." AND expires!=0 AND expired!=1 324 "); 325 while($warning = $db->fetch_array($query)) 326 { 327 $updated_warning = array( 328 "expired" => 1 329 ); 330 $db->update_query("warnings", $updated_warning, "wid='{$warning['wid']}'"); 331 332 if(array_key_exists($warning['uid'], $users)) 333 { 334 $users[$warning['uid']] -= $warning['points']; 335 } 336 else 337 { 338 $users[$warning['uid']] = $warning['warningpoints']-$warning['points']; 339 } 340 } 341 342 foreach($users as $uid => $warningpoints) 343 { 344 if($warningpoints < 0) 345 { 346 $warningpoints = 0; 347 } 348 349 $updated_user = array( 350 "warningpoints" => (int)$warningpoints 351 ); 352 $db->update_query("users", $updated_user, "uid='".(int)$uid."'"); 353 } 354 355 return true; 356 } 357 358 /** 359 * Updates an user warning details. 360 * 361 * @return array Updated user details. 362 */ 363 function update_user($method='insert') 364 { 365 global $db, $mybb, $lang, $cache, $groupscache; 366 367 if($mybb->settings['maxwarningpoints'] < 1) 368 { 369 $mybb->settings['maxwarningpoints'] = 10; 370 } 371 372 if(!is_array($groupscache)) 373 { 374 $groupscache = $cache->read("usergroups"); 375 } 376 377 $warning = &$this->data; 378 379 $user = get_user($warning['uid']); 380 381 if($method == 'insert') 382 { 383 // Build warning level & ensure it doesn't go over 100. 384 $current_level = round($user['warningpoints']/$mybb->settings['maxwarningpoints']*100); 385 $this->new_warning_level = round(($user['warningpoints']+$warning['points'])/$mybb->settings['maxwarningpoints']*100); 386 if($this->new_warning_level > 100) 387 { 388 $this->new_warning_level = 100; 389 } 390 391 // Update user 392 $this->updated_user = array( 393 "warningpoints" => $user['warningpoints']+$warning['points'] 394 ); 395 396 // Fetch warning level 397 $query = $db->simple_select("warninglevels", "*", "percentage<={$this->new_warning_level}", array("order_by" => "percentage", "order_dir" => "desc")); 398 $new_level = $db->fetch_array($query); 399 400 if(!empty($new_level) && $new_level['lid']) 401 { 402 $expiration = 0; 403 $action = my_unserialize($new_level['action']); 404 405 if($action['length'] > 0) 406 { 407 $expiration = TIME_NOW+$action['length']; 408 } 409 410 switch($action['type']) 411 { 412 // Ban the user for a specified time 413 case 1: 414 if(empty($groupscache[$action['usergroup']]) || $groupscache[$action['usergroup']]['isbannedgroup'] != 1) 415 { 416 break; 417 } 418 419 // Fetch any previous bans for this user 420 $query = $db->simple_select("banned", "*", "uid='{$user['uid']}' AND gid='{$action['usergroup']}' AND lifted>".TIME_NOW); 421 $existing_ban = $db->fetch_array($query); 422 423 // Only perform if no previous ban or new ban expires later than existing ban 424 if(($expiration > $existing_ban['lifted'] && $existing_ban['lifted'] != 0) || $expiration == 0 || !$existing_ban['uid']) 425 { 426 if(!$warning['title']) 427 { 428 $warning['title'] = $this->warning_type['title']; 429 } 430 431 // Never lift the ban? 432 if($action['length'] <= 0) 433 { 434 $bantime = '---'; 435 } 436 else 437 { 438 $bantimes = fetch_ban_times(); 439 foreach($bantimes as $date => $string) 440 { 441 if($date == '---') 442 { 443 continue; 444 } 445 446 $time = 0; 447 list($day, $month, $year) = explode('-', $date); 448 if($day > 0) 449 { 450 $time += 60*60*24*$day; 451 } 452 453 if($month > 0) 454 { 455 $time += 60*60*24*30*$month; 456 } 457 458 if($year > 0) 459 { 460 $time += 60*60*24*365*$year; 461 } 462 463 if($time == $action['length']) 464 { 465 $bantime = $date; 466 break; 467 } 468 } 469 } 470 471 $new_ban = array( 472 "uid" => $user['uid'], 473 "gid" => $action['usergroup'], 474 "oldgroup" => $user['usergroup'], 475 "oldadditionalgroups" => $db->escape_string($user['additionalgroups']), 476 "olddisplaygroup" => $user['displaygroup'], 477 "admin" => $mybb->user['uid'], 478 "dateline" => TIME_NOW, 479 "bantime" => $db->escape_string($bantime), 480 "lifted" => $expiration, 481 "reason" => $db->escape_string($warning['title']) 482 ); 483 // Delete old ban for this user, taking details 484 if($existing_ban['uid']) 485 { 486 $db->delete_query("banned", "uid='{$user['uid']}' AND gid='{$action['usergroup']}'"); 487 // Override new ban details with old group info 488 $new_ban['oldgroup'] = $existing_ban['oldgroup']; 489 $new_ban['oldadditionalgroups'] = $db->escape_string($existing_ban['oldadditionalgroups']); 490 $new_ban['olddisplaygroup'] = $existing_ban['olddisplaygroup']; 491 } 492 493 $period = $lang->expiration_never; 494 $ban_length = fetch_friendly_expiration($action['length']); 495 496 if($ban_length['time']) 497 { 498 $lang_str = "expiration_".$ban_length['period']; 499 $period = $lang->sprintf($lang->result_period, $ban_length['time'], $lang->$lang_str); 500 } 501 502 $group_name = $groupscache[$action['usergroup']]['title']; 503 $this->friendly_action = $lang->sprintf($lang->redirect_warned_banned, $group_name, $period); 504 505 $db->insert_query("banned", $new_ban); 506 $this->updated_user['usergroup'] = $action['usergroup']; 507 $this->updated_user['additionalgroups'] = ''; 508 $this->updated_user['displaygroup'] = 0; 509 } 510 break; 511 // Suspend posting privileges 512 case 2: 513 // Only perform if the expiration time is greater than the users current suspension period 514 if($expiration == 0 || $expiration > $user['suspensiontime']) 515 { 516 if(($user['suspensiontime'] != 0 && $user['suspendposting']) || !$user['suspendposting']) 517 { 518 $period = $lang->expiration_never; 519 $ban_length = fetch_friendly_expiration($action['length']); 520 521 if($ban_length['time']) 522 { 523 $lang_str = "expiration_".$ban_length['period']; 524 $period = $lang->sprintf($lang->result_period, $ban_length['time'], $lang->$lang_str); 525 } 526 527 $this->friendly_action = $lang->sprintf($lang->redirect_warned_suspended, $period); 528 529 $this->updated_user['suspensiontime'] = $expiration; 530 $this->updated_user['suspendposting'] = 1; 531 } 532 } 533 break; 534 // Moderate new posts 535 case 3: 536 // Only perform if the expiration time is greater than the users current suspension period 537 if($expiration == 0 || $expiration > $user['moderationtime']) 538 { 539 if(($user['moderationtime'] != 0 && $user['moderateposts']) || !$user['suspendposting']) 540 { 541 $period = $lang->expiration_never; 542 $ban_length = fetch_friendly_expiration($action['length']); 543 544 if($ban_length['time']) 545 { 546 $lang_str = "expiration_".$ban_length['period']; 547 $period = $lang->sprintf($lang->result_period, $ban_length['time'], $lang->$lang_str); 548 } 549 550 $this->friendly_action = $lang->sprintf($lang->redirect_warned_moderate, $period); 551 552 $this->updated_user['moderationtime'] = $expiration; 553 $this->updated_user['moderateposts'] = 1; 554 } 555 } 556 break; 557 } 558 } 559 } 560 else 561 { 562 // Warning is still active, lower users point count 563 if($warning['expired'] != 1) 564 { 565 $new_warning_points = $user['warningpoints']-$warning['points']; 566 if($new_warning_points < 0) 567 { 568 $new_warning_points = 0; 569 } 570 571 $this->updated_user = array( 572 "warningpoints" => $new_warning_points 573 ); 574 575 576 // check if we need to revoke any consequences with this warning 577 $current_level = round($user['warningpoints']/$mybb->settings['maxwarningpoints']*100); 578 $this->new_warning_level = round($new_warning_points/$mybb->settings['maxwarningpoints']*100); 579 $query = $db->simple_select("warninglevels", "action", "percentage>{$this->new_warning_level} AND percentage<=$current_level"); 580 if($db->num_rows($query)) 581 { 582 // we have some warning levels we need to revoke 583 $max_expiration_times = $check_levels = array(); 584 find_warnlevels_to_check($query, $max_expiration_times, $check_levels); 585 586 // now check warning levels already applied to this user to see if we need to lower any expiration times 587 $query = $db->simple_select("warninglevels", "action", "percentage<={$this->new_warning_level}"); 588 $lower_expiration_times = $lower_levels = array(); 589 find_warnlevels_to_check($query, $lower_expiration_times, $lower_levels); 590 591 // now that we've got all the info, do necessary stuff 592 for($i = 1; $i <= 3; ++$i) 593 { 594 if($check_levels[$i]) 595 { 596 switch($i) 597 { 598 case 1: // Ban 599 // we'll have to resort to letting the admin/mod remove the ban manually, since there's an issue if stacked bans are in force... 600 continue 2; 601 case 2: // Revoke posting 602 $current_expiry_field = 'suspensiontime'; 603 $current_inforce_field = 'suspendposting'; 604 break; 605 case 3: 606 $current_expiry_field = 'moderationtime'; 607 $current_inforce_field = 'moderateposts'; 608 break; 609 } 610 611 // if the thing isn't in force, don't bother with trying to update anything 612 if(!$user[$current_inforce_field]) 613 { 614 continue; 615 } 616 617 if($lower_levels[$i]) 618 { 619 // lessen the expiration time if necessary 620 621 if(!$lower_expiration_times[$i]) 622 { 623 // doesn't expire - enforce this 624 $this->updated_user[$current_expiry_field] = 0; 625 continue; 626 } 627 628 if($max_expiration_times[$i]) 629 { 630 // if the old level did have an expiry time... 631 if($max_expiration_times[$i] <= $lower_expiration_times[$i]) 632 { 633 // if the lower expiration time is actually higher than the upper expiration time -> skip 634 continue; 635 } 636 // both new and old max expiry times aren't infinite, so we can take a difference 637 $expire_offset = ($lower_expiration_times[$i] - $max_expiration_times[$i]); 638 } 639 else 640 { 641 // the old level never expired, not much we can do but try to estimate a new expiry time... which will just happen to be starting from today... 642 $expire_offset = TIME_NOW + $lower_expiration_times[$i]; 643 // if the user's expiry time is already less than what we're going to set it to, skip 644 if($user[$current_expiry_field] <= $expire_offset) 645 { 646 continue; 647 } 648 } 649 650 $this->updated_user[$current_expiry_field] = $user[$current_expiry_field] + $expire_offset; 651 // double-check if it's expired already 652 if($this->updated_user[$current_expiry_field] < TIME_NOW) 653 { 654 $this->updated_user[$current_expiry_field] = 0; 655 $this->updated_user[$current_inforce_field] = 0; 656 } 657 } 658 else 659 { 660 // there's no lower level for this type - remove the consequence entirely 661 $this->updated_user[$current_expiry_field] = 0; 662 $this->updated_user[$current_inforce_field] = 0; 663 } 664 } 665 } 666 } 667 } 668 } 669 670 // Save updated details 671 $db->update_query("users", $this->updated_user, "uid='{$user['uid']}'"); 672 673 $mybb->cache->update_moderators(); 674 675 return $this->updated_user; 676 } 677 678 /** 679 * Inserts a warning into the database 680 * 681 * @return array Warning database details. 682 */ 683 function insert_warning() 684 { 685 global $db, $mybb, $plugins; 686 687 $warning = &$this->data; 688 689 $this->write_warning_data = array( 690 "uid" => (int)$warning['uid'], 691 "tid" => (int)$warning['type'], 692 "pid" => isset($warning['pid']) ? (int)$warning['pid'] : 0, 693 "title" => $db->escape_string($warning['title']), 694 "points" => (int)$warning['points'], 695 "dateline" => TIME_NOW, 696 "issuedby" => $mybb->user['uid'], 697 "expires" => (int)$warning['expires'], 698 "expired" => 0, 699 "revokereason" => '', 700 "notes" => $db->escape_string($warning['notes']) 701 ); 702 703 $this->write_warning_data['wid'] = $db->insert_query("warnings", $this->write_warning_data); 704 705 $this->update_user(); 706 707 $plugins->run_hooks("datahandler_warnings_insert_warning", $this); 708 709 return $this->write_warning_data; 710 } 711 712 /** 713 * Updates a warning in the database 714 * 715 * @return array|false Warning database details. 716 */ 717 function update_warning() 718 { 719 global $db, $mybb, $plugins; 720 721 $warning = &$this->data; 722 723 $warning['wid'] = (int)$warning['wid']; 724 if($warning['wid'] <= 0) 725 { 726 return false; 727 } 728 729 $this->write_warning_data = array( 730 "expired" => 1, 731 "daterevoked" => TIME_NOW, 732 "revokedby" => $mybb->user['uid'], 733 "revokereason" => $db->escape_string($warning['reason']) 734 ); 735 736 $plugins->run_hooks("datahandler_warnings_update_warning", $this); 737 738 $db->update_query("warnings", $this->write_warning_data, "wid='{$warning['wid']}'"); 739 740 $this->update_user('update'); 741 742 return $this->write_warning_data; 743 } 744 745 } 746
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| 2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup | Cross-referenced by PHPXref |