| [ Index ] |
PHP Cross Reference of MyBB 1.8.40 |
[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 /** 12 * Build a select box list of forums the current user has permission to search 13 * 14 * @param int $pid The parent forum ID to start at 15 * @param int $selitem The selected forum ID 16 * @param int $addselect Add select boxes at this call or not 17 * @param string $depth The current depth 18 * @return string The forum select boxes 19 */ 20 function make_searchable_forums($pid=0, $selitem=0, $addselect=1, $depth='') 21 { 22 global $db, $pforumcache, $permissioncache, $mybb, $selecteddone, $forumlist, $forumlistbits, $theme, $templates, $lang, $forumpass; 23 $pid = (int)$pid; 24 25 if(!is_array($pforumcache)) 26 { 27 // Get Forums 28 $query = $db->simple_select("forums", "pid,disporder,fid,password,name", "linkto='' AND active!=0", array('order_by' => "pid, disporder")); 29 while($forum = $db->fetch_array($query)) 30 { 31 $pforumcache[$forum['pid']][$forum['disporder']][$forum['fid']] = $forum; 32 } 33 } 34 if(!is_array($permissioncache)) 35 { 36 $permissioncache = forum_permissions(); 37 } 38 if(is_array($pforumcache[$pid])) 39 { 40 foreach($pforumcache[$pid] as $key => $main) 41 { 42 foreach($main as $key => $forum) 43 { 44 $perms = $permissioncache[$forum['fid']]; 45 if(($perms['canview'] == 1 || $mybb->settings['hideprivateforums'] == 0) && $perms['cansearch'] != 0) 46 { 47 if($selitem == $forum['fid']) 48 { 49 $optionselected = "selected"; 50 $selecteddone = "1"; 51 } 52 else 53 { 54 $optionselected = ''; 55 $selecteddone = "0"; 56 } 57 if(forum_password_validated($forum, true)) 58 { 59 eval("\$forumlistbits .= \"".$templates->get("search_forumlist_forum")."\";"); 60 } 61 if(!empty($pforumcache[$forum['fid']])) 62 { 63 $newdepth = $depth." "; 64 $forumlistbits .= make_searchable_forums($forum['fid'], $selitem, 0, $newdepth); 65 } 66 } 67 } 68 } 69 } 70 if($addselect) 71 { 72 eval("\$forumlist = \"".$templates->get("search_forumlist")."\";"); 73 } 74 return $forumlist; 75 } 76 77 /** 78 * Build a comma separated list of the forums this user cannot search 79 * 80 * @param int $pid The parent ID to build from 81 * @param int $first First rotation or not (leave at default) 82 * @return string return a CSV list of forums the user cannot search 83 */ 84 function get_unsearchable_forums($pid=0, $first=1) 85 { 86 global $forum_cache, $permissioncache, $mybb, $unsearchableforums, $unsearchable, $templates, $forumpass; 87 88 $pid = (int)$pid; 89 90 if(!is_array($forum_cache)) 91 { 92 cache_forums(); 93 } 94 if(!is_array($permissioncache)) 95 { 96 $permissioncache = forum_permissions(); 97 } 98 foreach($forum_cache as $fid => $forum) 99 { 100 if($permissioncache[$forum['fid']]) 101 { 102 $perms = $permissioncache[$forum['fid']]; 103 } 104 else 105 { 106 $perms = $mybb->usergroup; 107 } 108 109 $parents = explode(",", $forum['parentlist']); 110 if(is_array($parents)) 111 { 112 foreach($parents as $parent) 113 { 114 if($forum_cache[$parent]['active'] == 0) 115 { 116 $forum['active'] = 0; 117 } 118 } 119 } 120 121 if($perms['canview'] != 1 || $perms['cansearch'] != 1 || !forum_password_validated($forum, true) || $forum['active'] == 0) 122 { 123 if($unsearchableforums) 124 { 125 $unsearchableforums .= ","; 126 } 127 $unsearchableforums .= "'{$forum['fid']}'"; 128 } 129 } 130 $unsearchable = $unsearchableforums; 131 132 // Get our unsearchable password protected forums 133 $pass_protected_forums = get_password_protected_forums(); 134 135 if($unsearchable && $pass_protected_forums) 136 { 137 $unsearchable .= ","; 138 } 139 140 if($pass_protected_forums) 141 { 142 $unsearchable .= implode(",", $pass_protected_forums); 143 } 144 145 return $unsearchable; 146 } 147 148 /** 149 * Build query condition for threads/posts the user is allowed to see. 150 * Will return for example: 151 * - visible = 1 - for normal users 152 * - visible >= -1 - for admins & super mods 153 * - (visible = 1 OR (visible = ? AND fid IN ...)) - for forum moderators 154 * 155 * @param string $table_alias The alias of the table eg t to use t.visible instead of visible 156 * @return string the query condition 157 */ 158 function get_visible_where($table_alias = null) 159 { 160 global $db, $mybb; 161 162 $aliasdot = ''; 163 if(!empty($table_alias)) 164 { 165 $aliasdot = $table_alias.'.'; 166 } 167 168 if($mybb->usergroup['issupermod'] == 1) 169 { 170 // Super moderators (and admins) 171 return "{$aliasdot}visible >= -1"; 172 } 173 elseif(is_moderator()) 174 { 175 // Normal moderators 176 $unapprove_forums = array(); 177 $deleted_forums = array(); 178 $unapproved_where = "({$aliasdot}visible = 1"; 179 180 $moderated_fids = get_moderated_fids($mybb->user['uid']); 181 182 if($moderated_fids !== false) 183 { 184 foreach($moderated_fids as $fid) 185 { 186 if(!is_moderator($fid)) 187 { 188 // Shouldn't occur. 189 continue; 190 } 191 192 // Use moderates this forum 193 $modperms = get_moderator_permissions($fid, $mybb->user['uid']); 194 195 if($modperms['canviewunapprove'] == 1) 196 { 197 $unapprove_forums[] = $fid; 198 } 199 200 if($modperms['canviewdeleted'] == 1) 201 { 202 $deleted_forums[] = $fid; 203 } 204 } 205 206 if(!empty($unapprove_forums)) 207 { 208 $unapproved_where .= " OR ({$aliasdot}visible = 0 AND {$aliasdot}fid IN(".implode(',', $unapprove_forums)."))"; 209 } 210 if(!empty($deleted_forums)) 211 { 212 $unapproved_where .= " OR ({$aliasdot}visible = -1 AND {$aliasdot}fid IN(".implode(',', $deleted_forums)."))"; 213 } 214 $unapproved_where .= ')'; 215 216 return $unapproved_where; 217 } 218 } 219 220 // Normal users 221 if($mybb->user['uid'] > 0 && $mybb->settings['showownunapproved'] == 1) 222 { 223 return "({$aliasdot}visible = 1 OR ({$aliasdot}visible = 0 AND {$aliasdot}uid = {$mybb->user['uid']}))"; 224 } 225 return "{$aliasdot}visible = 1"; 226 } 227 228 /** 229 * Build a array list of the forums this user cannot search due to password protection 230 * 231 * @param array $fids the fids to check (leave blank to check all forums) 232 * @return array|false return a array list of password protected forums the user cannot search 233 */ 234 function get_password_protected_forums($fids=array()) 235 { 236 global $forum_cache, $mybb; 237 238 if(!is_array($fids)) 239 { 240 return false; 241 } 242 243 if(!is_array($forum_cache)) 244 { 245 $forum_cache = cache_forums(); 246 if(!$forum_cache) 247 { 248 return false; 249 } 250 } 251 252 if(empty($fids)) 253 { 254 $fids = array_keys($forum_cache); 255 } 256 257 $pass_fids = array(); 258 foreach($fids as $fid) 259 { 260 if(!forum_password_validated($forum_cache[$fid], true)) 261 { 262 $pass_fids[] = $fid; 263 $pass_fids = array_merge($pass_fids, get_child_list($fid)); 264 } 265 } 266 return array_unique($pass_fids); 267 } 268 269 /** 270 * Clean search keywords and make them safe for querying 271 * 272 * @param string $keywords The keywords to be cleaned 273 * @return string The cleaned keywords 274 */ 275 function clean_keywords($keywords) 276 { 277 global $db, $lang; 278 279 $keywords = my_strtolower($keywords); 280 $keywords = $db->escape_string_like($keywords); 281 $keywords = preg_replace("#\*{2,}#s", "*", $keywords); 282 $keywords = str_replace("*", "%", $keywords); 283 $keywords = preg_replace("#\s+#s", " ", $keywords); 284 $keywords = str_replace('\\"', '"', $keywords); 285 // trim for blank characters 286 $keywords = trim($keywords); 287 // Search for "and" or "or" and remove if it's at the beginning 288 $keywords = preg_replace('/^((and|or)(\s|$))+/', '', $keywords); 289 290 if(!$keywords) 291 { 292 error($lang->error_nosearchterms); 293 } 294 295 return $keywords; 296 } 297 298 /** 299 * Clean search keywords for fulltext searching, making them safe for querying 300 * 301 * @param string $keywords The keywords to be cleaned 302 * @return string|bool The cleaned keywords or false on failure 303 */ 304 function clean_keywords_ft($keywords) 305 { 306 if(!$keywords) 307 { 308 return false; 309 } 310 $keywords = my_strtolower($keywords); 311 $keywords = str_replace("%", "\\%", $keywords); 312 $keywords = preg_replace("#\*{2,}#s", "*", $keywords); 313 $keywords = preg_replace("#([\[\]\|\.\,:])#s", " ", $keywords); 314 // Separate braces for further processing 315 $keywords = preg_replace("#((\+|-|<|>|~)?\(|\))#s", " $1 ", $keywords); 316 $keywords = preg_replace("#\s+#s", " ", $keywords); 317 318 global $mybb; 319 320 $min_word_length = (int) $mybb->settings['minsearchword']; 321 if($min_word_length <= 0) 322 { 323 $min_word_length = 3; 324 } 325 $min_word_length -= 1; 326 327 $word_length_regex = ''; 328 if($min_word_length > 1) 329 { 330 $word_length_regex = "{1,{$min_word_length}}"; 331 } 332 333 // Replaces less than 3 characters 334 $keywords = preg_replace("/(\b.{$word_length_regex})(\s)|(\b.{$word_length_regex}$)/u", '$2', $keywords); 335 // Collapse multiple spaces 336 $keywords = preg_replace('/(\s)+/', '$1', $keywords); 337 $keywords = trim($keywords); 338 339 $words = array(array()); 340 341 // Fulltext search syntax validation: http://dev.mysql.com/doc/refman/5.6/en/fulltext-boolean.html 342 // Search for phrases 343 $keywords = explode("\"", $keywords); 344 $boolean = array('+'); 345 // Brace depth 346 $depth = 0; 347 $phrase_operator = '+'; 348 $inquote = false; 349 foreach($keywords as $phrase) 350 { 351 $phrase = trim($phrase); 352 if($phrase != '') 353 { 354 if($inquote) 355 { 356 if($phrase_operator) 357 { 358 $boolean[$depth] = $phrase_operator; 359 } 360 // Phrases do not need further processing 361 $words[$depth][] = "{$boolean[$depth]}\"{$phrase}\""; 362 $boolean[$depth] = $phrase_operator = '+'; 363 } 364 else 365 { 366 // Split words 367 $split_words = preg_split("#\s{1,}#", $phrase, -1); 368 if(!is_array($split_words)) 369 { 370 continue; 371 } 372 if(!$inquote) 373 { 374 // Save possible operator in front of phrase 375 $last_char = substr($phrase, -1); 376 if($last_char == '+' || $last_char == '-' || $last_char == '<' || $last_char == '>' || $last_char == '~') 377 { 378 $phrase_operator = $last_char; 379 } 380 } 381 foreach($split_words as $word) 382 { 383 $word = trim($word); 384 if($word == "or") 385 { 386 $boolean[$depth] = ''; 387 // Remove "and" operator from previous element 388 $last = array_pop($words[$depth]); 389 if($last) 390 { 391 if(substr($last, 0, 1) == '+') 392 { 393 $last = substr($last, 1); 394 } 395 $words[$depth][] = $last; 396 } 397 } 398 elseif($word == "and") 399 { 400 $boolean[$depth] = "+"; 401 } 402 elseif($word == "not") 403 { 404 $boolean[$depth] = "-"; 405 } 406 // Closing braces 407 elseif($word == ")") 408 { 409 // Ignore when no brace was opened 410 if($depth > 0) 411 { 412 $words[$depth-1][] = $boolean[$depth-1].'('.implode(' ', $words[$depth]).')'; 413 --$depth; 414 } 415 } 416 // Valid operators for opening braces 417 elseif($word == '+(' || $word == '-(' || $word == '<(' || $word == '>(' || $word == '~(' || $word == '(') 418 { 419 if(strlen($word) == 2) 420 { 421 $boolean[$depth] = substr($word, 0, 1); 422 } 423 $words[++$depth] = array(); 424 $boolean[$depth] = '+'; 425 } 426 else 427 { 428 $operator = substr($word, 0, 1); 429 switch($operator) 430 { 431 // Allowed operators 432 case '-': 433 case '+': 434 case '>': 435 case '<': 436 case '~': 437 $word = substr($word, 1); 438 break; 439 default: 440 $operator = $boolean[$depth]; 441 break; 442 } 443 // Removed operators that are only allowed at the beginning 444 $word = preg_replace("#(-|\+|<|>|~|@)#s", '', $word); 445 // Removing wildcards at the beginning http://bugs.mysql.com/bug.php?id=72605 446 $word = preg_replace("#^\*#s", '', $word); 447 $word = $operator.$word; 448 if(strlen($word) <= 1) 449 { 450 continue; 451 } 452 $words[$depth][] = $word; 453 $boolean[$depth] = '+'; 454 } 455 } 456 } 457 } 458 $inquote = !$inquote; 459 } 460 461 // Close mismatching braces 462 while($depth > 0) 463 { 464 $words[$depth-1][] = $boolean[$depth-1].'('.implode(' ', $words[$depth]).')'; 465 --$depth; 466 } 467 468 $keywords = implode(' ', $words[0]); 469 return $keywords; 470 } 471 472 /* Database engine specific search functions */ 473 474 /** 475 * Perform a thread and post search under MySQL or MySQLi 476 * 477 * @param array $search Array of search data 478 * @return array Array of search data with results mixed in 479 */ 480 function privatemessage_perform_search_mysql($search) 481 { 482 global $mybb, $db, $lang; 483 484 $keywords = clean_keywords($search['keywords']); 485 if(!$keywords && !$search['sender']) 486 { 487 error($lang->error_nosearchterms); 488 } 489 490 if($mybb->settings['minsearchword'] < 1) 491 { 492 $mybb->settings['minsearchword'] = 3; 493 } 494 495 $subject_lookin = ""; 496 $message_lookin = ""; 497 $searchsql = "uid='{$mybb->user['uid']}'"; 498 499 if($keywords) 500 { 501 // Complex search 502 $keywords = " {$keywords} "; 503 504 switch($db->type) 505 { 506 case 'mysql': 507 case 'mysqli': 508 $sfield = 'subject'; 509 $mfield = 'message'; 510 break; 511 default: 512 $sfield = 'LOWER(subject)'; 513 $mfield = 'LOWER(message)'; 514 break; 515 } 516 517 if(preg_match("#\s(and|or)\s#", $keywords)) 518 { 519 $string = "AND"; 520 if($search['subject'] == 1) 521 { 522 $string = "OR"; 523 $subject_lookin = " AND ("; 524 } 525 526 if($search['message'] == 1) 527 { 528 $message_lookin = " {$string} ("; 529 } 530 531 // Expand the string by double quotes 532 $keywords_exp = explode("\"", $keywords); 533 $inquote = false; 534 $boolean = ''; 535 536 foreach($keywords_exp as $phrase) 537 { 538 // If we're not in a double quoted section 539 if(!$inquote) 540 { 541 // Expand out based on search operators (and, or) 542 $matches = preg_split("#\s{1,}(and|or)\s{1,}#", $phrase, -1, PREG_SPLIT_DELIM_CAPTURE); 543 $count_matches = count($matches); 544 545 for($i=0; $i < $count_matches; ++$i) 546 { 547 $word = trim($matches[$i]); 548 if(empty($word)) 549 { 550 continue; 551 } 552 // If this word is a search operator set the boolean 553 if($i % 2 && ($word == "and" || $word == "or")) 554 { 555 if($i <= 1) 556 { 557 if($search['subject'] && $search['message'] && $subject_lookin == " AND (") 558 { 559 // We're looking for anything, check for a subject lookin 560 continue; 561 } 562 elseif($search['subject'] && !$search['message'] && $subject_lookin == " AND (") 563 { 564 // Just in a subject? 565 continue; 566 } 567 elseif(!$search['subject'] && $search['message'] && $message_lookin == " {$string} (") 568 { 569 // Just in a message? 570 continue; 571 } 572 } 573 574 $boolean = $word; 575 } 576 // Otherwise check the length of the word as it is a normal search term 577 else 578 { 579 $word = trim($word); 580 // Word is too short - show error message 581 if(my_strlen($word) < $mybb->settings['minsearchword']) 582 { 583 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 584 error($lang->error_minsearchlength); 585 } 586 587 // Add terms to search query 588 if($search['subject'] == 1) 589 { 590 $subject_lookin .= " $boolean {$sfield} LIKE '%{$word}%'"; 591 } 592 if($search['message'] == 1) 593 { 594 $message_lookin .= " $boolean {$mfield} LIKE '%{$word}%'"; 595 } 596 $boolean = 'AND'; 597 } 598 } 599 } 600 // In the middle of a quote (phrase) 601 else 602 { 603 $phrase = str_replace(array("+", "-", "*"), '', trim($phrase)); 604 if(my_strlen($phrase) < $mybb->settings['minsearchword']) 605 { 606 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 607 error($lang->error_minsearchlength); 608 } 609 // Add phrase to search query 610 $subject_lookin .= " $boolean {$sfield} LIKE '%{$phrase}%'"; 611 if($search['message'] == 1) 612 { 613 $message_lookin .= " $boolean {$mfield} LIKE '%{$phrase}%'"; 614 } 615 $boolean = 'AND'; 616 } 617 618 // Check to see if we have any search terms and not a malformed SQL string 619 $error = false; 620 if($search['subject'] && $search['message'] && $subject_lookin == " AND (") 621 { 622 // We're looking for anything, check for a subject lookin 623 $error = true; 624 } 625 elseif($search['subject'] && !$search['message'] && $subject_lookin == " AND (") 626 { 627 // Just in a subject? 628 $error = true; 629 } 630 elseif(!$search['subject'] && $search['message'] && $message_lookin == " {$string} (") 631 { 632 // Just in a message? 633 $error = true; 634 } 635 636 if($error == true) 637 { 638 // There are no search keywords to look for 639 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 640 error($lang->error_minsearchlength); 641 } 642 643 $inquote = !$inquote; 644 } 645 646 if($search['subject'] == 1) 647 { 648 $subject_lookin .= ")"; 649 } 650 651 if($search['message'] == 1) 652 { 653 $message_lookin .= ")"; 654 } 655 656 $searchsql .= "{$subject_lookin} {$message_lookin}"; 657 } 658 else 659 { 660 $keywords = str_replace("\"", '', trim($keywords)); 661 if(my_strlen($keywords) < $mybb->settings['minsearchword']) 662 { 663 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 664 error($lang->error_minsearchlength); 665 } 666 667 // If we're looking in both, then find matches in either the subject or the message 668 if($search['subject'] == 1 && $search['message'] == 1) 669 { 670 $searchsql .= " AND ({$sfield} LIKE '%{$keywords}%' OR {$mfield} LIKE '%{$keywords}%')"; 671 } 672 else 673 { 674 if($search['subject'] == 1) 675 { 676 $searchsql .= " AND {$sfield} LIKE '%{$keywords}%'"; 677 } 678 679 if($search['message'] == 1) 680 { 681 $searchsql .= " AND {$mfield} LIKE '%{$keywords}%'"; 682 } 683 } 684 } 685 } 686 687 if($search['sender']) 688 { 689 $userids = array(); 690 $search['sender'] = my_strtolower($search['sender']); 691 692 switch($db->type) 693 { 694 case 'mysql': 695 case 'mysqli': 696 $field = 'username'; 697 break; 698 default: 699 $field = 'LOWER(username)'; 700 break; 701 } 702 $query = $db->simple_select("users", "uid", "{$field} LIKE '%".$db->escape_string_like($search['sender'])."%'"); 703 while($user = $db->fetch_array($query)) 704 { 705 $userids[] = $user['uid']; 706 } 707 708 if(count($userids) < 1) 709 { 710 error($lang->error_nosearchresults); 711 } 712 else 713 { 714 $userids = implode(',', $userids); 715 $searchsql .= " AND fromid IN (".$userids.")"; 716 } 717 } 718 719 if(!is_array($search['folder'])) 720 { 721 $search['folder'] = array($search['folder']); 722 } 723 724 if(!empty($search['folder'])) 725 { 726 $folderids = array(); 727 728 $search['folder'] = array_map("intval", $search['folder']); 729 730 $folderids = implode(',', $search['folder']); 731 732 if($folderids) 733 { 734 $searchsql .= " AND folder IN (".$folderids.")"; 735 } 736 } 737 738 if($search['status']) 739 { 740 $searchsql .= " AND ("; 741 if($search['status']['new']) 742 { 743 $statussql[] = " status='0' "; 744 } 745 if($search['status']['replied']) 746 { 747 $statussql[] = " status='3' "; 748 } 749 if($search['status']['forwarded']) 750 { 751 $statussql[] = " status='4' "; 752 } 753 if($search['status']['read']) 754 { 755 $statussql[] = " (status != '0' AND readtime > '0') "; 756 } 757 // Sent Folder 758 if(in_array(2, $search['folder'])) 759 { 760 $statussql[] = " status='1' "; 761 } 762 $statussql = implode("OR", $statussql); 763 $searchsql .= $statussql.")"; 764 } 765 766 $limitsql = ""; 767 if((int)$mybb->settings['searchhardlimit'] > 0) 768 { 769 $limitsql = " LIMIT ".(int)$mybb->settings['searchhardlimit']; 770 } 771 $searchsql .= $limitsql; 772 773 // Run the search 774 $pms = array(); 775 $query = $db->simple_select("privatemessages", "pmid", $searchsql); 776 while($pm = $db->fetch_array($query)) 777 { 778 $pms[$pm['pmid']] = $pm['pmid']; 779 } 780 781 if(count($pms) < 1) 782 { 783 error($lang->error_nosearchresults); 784 } 785 $pms = implode(',', $pms); 786 787 return array( 788 "querycache" => $pms 789 ); 790 } 791 792 /** 793 * Perform a help document search under MySQL or MySQLi 794 * 795 * @param array $search Array of search data 796 * @return array Array of search data with results mixed in 797 */ 798 function helpdocument_perform_search_mysql($search) 799 { 800 global $mybb, $db, $lang; 801 802 $keywords = clean_keywords($search['keywords']); 803 if(!$keywords && !$search['sender']) 804 { 805 error($lang->error_nosearchterms); 806 } 807 808 if($mybb->settings['minsearchword'] < 1) 809 { 810 $mybb->settings['minsearchword'] = 3; 811 } 812 813 $name_lookin = ""; 814 $document_lookin = ""; 815 $searchsql = "enabled='1'"; 816 817 if($keywords) 818 { 819 switch($db->type) 820 { 821 case 'mysql': 822 case 'mysqli': 823 $nfield = 'name'; 824 $dfield = 'document'; 825 break; 826 default: 827 $nfield = 'LOWER(name)'; 828 $dfield = 'LOWER(document)'; 829 break; 830 } 831 832 // Complex search 833 $keywords = " {$keywords} "; 834 if(preg_match("#\s(and|or)\s#", $keywords)) 835 { 836 $string = "AND"; 837 if($search['name'] == 1) 838 { 839 $string = "OR"; 840 $name_lookin = " AND ("; 841 } 842 843 if($search['document'] == 1) 844 { 845 $document_lookin = " {$string} ("; 846 } 847 848 // Expand the string by double quotes 849 $keywords_exp = explode("\"", $keywords); 850 $inquote = false; 851 852 $boolean = ''; 853 854 foreach($keywords_exp as $phrase) 855 { 856 // If we're not in a double quoted section 857 if(!$inquote) 858 { 859 // Expand out based on search operators (and, or) 860 $matches = preg_split("#\s{1,}(and|or)\s{1,}#", $phrase, -1, PREG_SPLIT_DELIM_CAPTURE); 861 $count_matches = count($matches); 862 863 for($i=0; $i < $count_matches; ++$i) 864 { 865 $word = trim($matches[$i]); 866 if(empty($word)) 867 { 868 continue; 869 } 870 // If this word is a search operator set the boolean 871 if($i % 2 && ($word == "and" || $word == "or")) 872 { 873 if($i <= 1) 874 { 875 if($search['name'] && $search['document'] && $name_lookin == " AND (") 876 { 877 // We're looking for anything, check for a name lookin 878 continue; 879 } 880 elseif($search['name'] && !$search['document'] && $name_lookin == " AND (") 881 { 882 // Just in a name? 883 continue; 884 } 885 elseif(!$search['name'] && $search['document'] && $document_lookin == " {$string} (") 886 { 887 // Just in a document? 888 continue; 889 } 890 } 891 892 $boolean = $word; 893 } 894 // Otherwise check the length of the word as it is a normal search term 895 else 896 { 897 $word = trim($word); 898 // Word is too short - show error message 899 if(my_strlen($word) < $mybb->settings['minsearchword']) 900 { 901 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 902 error($lang->error_minsearchlength); 903 } 904 // Add terms to search query 905 if($search['name'] == 1) 906 { 907 $name_lookin .= " $boolean {$nfield} LIKE '%{$word}%'"; 908 } 909 if($search['document'] == 1) 910 { 911 $document_lookin .= " $boolean {$dfield} LIKE '%{$word}%'"; 912 } 913 914 $boolean = 'AND'; 915 } 916 } 917 } 918 // In the middle of a quote (phrase) 919 else 920 { 921 $phrase = str_replace(array("+", "-", "*"), '', trim($phrase)); 922 if(my_strlen($phrase) < $mybb->settings['minsearchword']) 923 { 924 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 925 error($lang->error_minsearchlength); 926 } 927 // Add phrase to search query 928 $name_lookin .= " $boolean {$nfield} LIKE '%{$phrase}%'"; 929 if($search['document'] == 1) 930 { 931 $document_lookin .= " $boolean {$dfield} LIKE '%{$phrase}%'"; 932 } 933 934 $boolean = 'AND'; 935 } 936 937 // Check to see if we have any search terms and not a malformed SQL string 938 $error = false; 939 if($search['name'] && $search['document'] && $name_lookin == " AND (") 940 { 941 // We're looking for anything, check for a name lookin 942 $error = true; 943 } 944 elseif($search['name'] && !$search['document'] && $name_lookin == " AND (") 945 { 946 // Just in a name? 947 $error = true; 948 } 949 elseif(!$search['name'] && $search['document'] && $document_lookin == " {$string} (") 950 { 951 // Just in a document? 952 $error = true; 953 } 954 955 if($error == true) 956 { 957 // There are no search keywords to look for 958 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 959 error($lang->error_minsearchlength); 960 } 961 962 $inquote = !$inquote; 963 } 964 965 if($search['name'] == 1) 966 { 967 $name_lookin .= ")"; 968 } 969 970 if($search['document'] == 1) 971 { 972 $document_lookin .= ")"; 973 } 974 975 $searchsql .= "{$name_lookin} {$document_lookin}"; 976 } 977 else 978 { 979 $keywords = str_replace("\"", '', trim($keywords)); 980 if(my_strlen($keywords) < $mybb->settings['minsearchword']) 981 { 982 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 983 error($lang->error_minsearchlength); 984 } 985 986 // If we're looking in both, then find matches in either the name or the document 987 if($search['name'] == 1 && $search['document'] == 1) 988 { 989 $searchsql .= " AND ({$nfield} LIKE '%{$keywords}%' OR {$dfield} LIKE '%{$keywords}%')"; 990 } 991 else 992 { 993 if($search['name'] == 1) 994 { 995 $searchsql .= " AND {$nfield} LIKE '%{$keywords}%'"; 996 } 997 998 if($search['document'] == 1) 999 { 1000 $searchsql .= " AND {$dfield} LIKE '%{$keywords}%'"; 1001 } 1002 } 1003 } 1004 } 1005 1006 // Run the search 1007 $helpdocs = array(); 1008 $query = $db->simple_select("helpdocs", "hid", $searchsql); 1009 while($help = $db->fetch_array($query)) 1010 { 1011 $helpdocs[$help['hid']] = $help['hid']; 1012 } 1013 1014 if(count($helpdocs) < 1) 1015 { 1016 error($lang->error_nosearchresults); 1017 } 1018 $helpdocs = implode(',', $helpdocs); 1019 1020 return array( 1021 "querycache" => $helpdocs 1022 ); 1023 } 1024 1025 /** 1026 * Perform a thread and post search under MySQL or MySQLi 1027 * 1028 * @param array $search Array of search data 1029 * @return array Array of search data with results mixed in 1030 */ 1031 function perform_search_mysql($search) 1032 { 1033 global $mybb, $db, $lang, $cache; 1034 1035 $keywords = clean_keywords($search['keywords']); 1036 1037 if($mybb->settings['minsearchword'] < 1) 1038 { 1039 $mybb->settings['minsearchword'] = 3; 1040 } 1041 1042 $subject_lookin = $message_lookin = ''; 1043 if($keywords) 1044 { 1045 switch($db->type) 1046 { 1047 case 'mysql': 1048 case 'mysqli': 1049 $tfield = 't.subject'; 1050 $pfield = 'p.message'; 1051 break; 1052 default: 1053 $tfield = 'LOWER(t.subject)'; 1054 $pfield = 'LOWER(p.message)'; 1055 break; 1056 } 1057 1058 // Complex search 1059 $keywords = " {$keywords} "; 1060 if(preg_match("#\s(and|or)\s#", $keywords)) 1061 { 1062 $subject_lookin = " AND ("; 1063 $message_lookin = " AND ("; 1064 1065 // Expand the string by double quotes 1066 $keywords_exp = explode("\"", $keywords); 1067 $inquote = false; 1068 $boolean = ''; 1069 1070 foreach($keywords_exp as $phrase) 1071 { 1072 // If we're not in a double quoted section 1073 if(!$inquote) 1074 { 1075 // Expand out based on search operators (and, or) 1076 $matches = preg_split("#\s{1,}(and|or)\s{1,}#", $phrase, -1, PREG_SPLIT_DELIM_CAPTURE); 1077 $count_matches = count($matches); 1078 1079 for($i=0; $i < $count_matches; ++$i) 1080 { 1081 $word = trim($matches[$i]); 1082 if(empty($word)) 1083 { 1084 continue; 1085 } 1086 // If this word is a search operator set the boolean 1087 if($i % 2 && ($word == "and" || $word == "or")) 1088 { 1089 if($i <= 1 && $subject_lookin == " AND (") 1090 { 1091 continue; 1092 } 1093 1094 $boolean = $word; 1095 } 1096 // Otherwise check the length of the word as it is a normal search term 1097 else 1098 { 1099 $word = trim($word); 1100 // Word is too short - show error message 1101 if(my_strlen($word) < $mybb->settings['minsearchword']) 1102 { 1103 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 1104 error($lang->error_minsearchlength); 1105 } 1106 // Add terms to search query 1107 $subject_lookin .= " $boolean {$tfield} LIKE '%{$word}%'"; 1108 if($search['postthread'] == 1) 1109 { 1110 $message_lookin .= " $boolean {$pfield} LIKE '%{$word}%'"; 1111 } 1112 $boolean = 'AND'; 1113 } 1114 } 1115 } 1116 // In the middle of a quote (phrase) 1117 else 1118 { 1119 $phrase = str_replace(array("+", "-", "*"), '', trim($phrase)); 1120 if(my_strlen($phrase) < $mybb->settings['minsearchword']) 1121 { 1122 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 1123 error($lang->error_minsearchlength); 1124 } 1125 // Add phrase to search query 1126 $subject_lookin .= " $boolean {$tfield} LIKE '%{$phrase}%'"; 1127 if($search['postthread'] == 1) 1128 { 1129 $message_lookin .= " $boolean {$pfield} LIKE '%{$phrase}%'"; 1130 } 1131 $boolean = 'AND'; 1132 } 1133 1134 if($subject_lookin == " AND (") 1135 { 1136 // There are no search keywords to look for 1137 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 1138 error($lang->error_minsearchlength); 1139 } 1140 1141 $inquote = !$inquote; 1142 } 1143 $subject_lookin .= ")"; 1144 $message_lookin .= ")"; 1145 } 1146 else 1147 { 1148 $keywords = str_replace("\"", '', trim($keywords)); 1149 if(my_strlen($keywords) < $mybb->settings['minsearchword']) 1150 { 1151 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 1152 error($lang->error_minsearchlength); 1153 } 1154 $subject_lookin = " AND {$tfield} LIKE '%{$keywords}%'"; 1155 if($search['postthread'] == 1) 1156 { 1157 $message_lookin = " AND {$pfield} LIKE '%{$keywords}%'"; 1158 } 1159 } 1160 } 1161 $post_usersql = ''; 1162 $thread_usersql = ''; 1163 if($search['author']) 1164 { 1165 $userids = array(); 1166 $search['author'] = my_strtolower($search['author']); 1167 if($search['matchusername']) 1168 { 1169 $user = get_user_by_username($search['author']); 1170 if($user) 1171 { 1172 $userids[] = $user['uid']; 1173 } 1174 } 1175 else 1176 { 1177 switch($db->type) 1178 { 1179 case 'mysql': 1180 case 'mysqli': 1181 $field = 'username'; 1182 break; 1183 default: 1184 $field = 'LOWER(username)'; 1185 break; 1186 } 1187 $query = $db->simple_select("users", "uid", "{$field} LIKE '%".$db->escape_string_like($search['author'])."%'"); 1188 while($user = $db->fetch_array($query)) 1189 { 1190 $userids[] = $user['uid']; 1191 } 1192 } 1193 1194 if(count($userids) < 1) 1195 { 1196 error($lang->error_nosearchresults); 1197 } 1198 else 1199 { 1200 $userids = implode(',', $userids); 1201 $post_usersql = " AND p.uid IN (".$userids.")"; 1202 $thread_usersql = " AND t.uid IN (".$userids.")"; 1203 } 1204 } 1205 $datecut = $post_datecut = $thread_datecut = ''; 1206 if($search['postdate']) 1207 { 1208 if($search['pddir'] == 0) 1209 { 1210 $datecut = "<="; 1211 } 1212 else 1213 { 1214 $datecut = ">="; 1215 } 1216 $now = TIME_NOW; 1217 $datelimit = $now-(86400 * $search['postdate']); 1218 $datecut .= "'$datelimit'"; 1219 $post_datecut = " AND p.dateline $datecut"; 1220 $thread_datecut = " AND t.dateline $datecut"; 1221 } 1222 1223 $thread_replycut = ''; 1224 if($search['numreplies'] != '' && $search['findthreadst']) 1225 { 1226 if((int)$search['findthreadst'] == 1) 1227 { 1228 $thread_replycut = " AND t.replies >= '".(int)$search['numreplies']."'"; 1229 } 1230 else 1231 { 1232 $thread_replycut = " AND t.replies <= '".(int)$search['numreplies']."'"; 1233 } 1234 } 1235 1236 $thread_prefixcut = ''; 1237 $prefixlist = array(); 1238 if(!empty($search['threadprefix']) && $search['threadprefix'][0] != 'any') 1239 { 1240 foreach($search['threadprefix'] as $threadprefix) 1241 { 1242 $threadprefix = (int)$threadprefix; 1243 $prefixlist[] = $threadprefix; 1244 } 1245 } 1246 if(count($prefixlist) == 1) 1247 { 1248 $thread_prefixcut .= " AND t.prefix='$threadprefix' "; 1249 } 1250 else 1251 { 1252 if(count($prefixlist) > 1) 1253 { 1254 $thread_prefixcut = " AND t.prefix IN (".implode(',', $prefixlist).")"; 1255 } 1256 } 1257 1258 $forumin = ''; 1259 $fidlist = array(); 1260 if(!empty($search['forums']) && (!is_array($search['forums']) || $search['forums'][0] != "all")) 1261 { 1262 if(!is_array($search['forums'])) 1263 { 1264 $search['forums'] = array((int)$search['forums']); 1265 } 1266 foreach($search['forums'] as $forum) 1267 { 1268 $forum = (int)$forum; 1269 if($forum > 0) 1270 { 1271 $fidlist[] = $forum; 1272 $child_list = get_child_list($forum); 1273 if(is_array($child_list)) 1274 { 1275 $fidlist = array_merge($fidlist, $child_list); 1276 } 1277 } 1278 } 1279 $fidlist = array_unique($fidlist); 1280 if(count($fidlist) >= 1) 1281 { 1282 $forumin = " AND t.fid IN (".implode(',', $fidlist).")"; 1283 } 1284 } 1285 1286 $permsql = ""; 1287 $onlyusfids = array(); 1288 1289 // Check group permissions if we can't view threads not started by us 1290 if($group_permissions = forum_permissions()) 1291 { 1292 foreach($group_permissions as $fid => $forum_permissions) 1293 { 1294 if(isset($forum_permissions['canonlyviewownthreads']) && $forum_permissions['canonlyviewownthreads'] == 1) 1295 { 1296 $onlyusfids[] = $fid; 1297 } 1298 } 1299 } 1300 if(!empty($onlyusfids)) 1301 { 1302 $permsql .= "AND ((t.fid IN(".implode(',', $onlyusfids).") AND t.uid='{$mybb->user['uid']}') OR t.fid NOT IN(".implode(',', $onlyusfids)."))"; 1303 } 1304 1305 $unsearchforums = get_unsearchable_forums(); 1306 if($unsearchforums) 1307 { 1308 $permsql .= " AND t.fid NOT IN ($unsearchforums)"; 1309 } 1310 $inactiveforums = get_inactive_forums(); 1311 if($inactiveforums) 1312 { 1313 $permsql .= " AND t.fid NOT IN ($inactiveforums)"; 1314 } 1315 1316 $visiblesql = $post_visiblesql = $plain_post_visiblesql = $unapproved_where_t = $unapproved_where_p = ""; 1317 if(isset($search['visible'])) 1318 { 1319 if($search['visible'] == 1) 1320 { 1321 $visiblesql = " AND t.visible = '1'"; 1322 1323 if($search['postthread'] == 1) 1324 { 1325 $post_visiblesql = " AND p.visible = '1'"; 1326 $plain_post_visiblesql = " AND visible = '1'"; 1327 } 1328 } 1329 elseif($search['visible'] == -1) 1330 { 1331 $visiblesql = " AND t.visible = '-1'"; 1332 1333 if($search['postthread'] == 1) 1334 { 1335 $post_visiblesql = " AND p.visible = '-1'"; 1336 $plain_post_visiblesql = " AND visible = '-1'"; 1337 } 1338 } 1339 else 1340 { 1341 $visiblesql = " AND t.visible == '0'"; 1342 1343 if($search['postthread'] == 1) 1344 { 1345 $post_visiblesql = " AND p.visible == '0'"; 1346 $plain_post_visiblesql = " AND visible == '0'"; 1347 } 1348 } 1349 } 1350 1351 // Moderators can view unapproved threads and deleted threads from forums they moderate 1352 $unapproved_where_t = get_visible_where('t'); 1353 $unapproved_where_p = get_visible_where('p'); 1354 1355 // Searching a specific thread? 1356 $tidsql = ''; 1357 if(!empty($search['tid'])) 1358 { 1359 $tidsql = " AND t.tid='".(int)$search['tid']."'"; 1360 } 1361 1362 $limitsql = ''; 1363 if((int)$mybb->settings['searchhardlimit'] > 0) 1364 { 1365 $limitsql = "LIMIT ".(int)$mybb->settings['searchhardlimit']; 1366 } 1367 1368 // Searching both posts and thread titles 1369 $threads = array(); 1370 $posts = array(); 1371 $firstposts = array(); 1372 if($search['postthread'] == 1) 1373 { 1374 // No need to search subjects when looking for results within a specific thread 1375 if(empty($search['tid'])) 1376 { 1377 $query = $db->query(" 1378 SELECT t.tid, t.firstpost 1379 FROM ".TABLE_PREFIX."threads t 1380 WHERE 1=1 {$thread_datecut} {$thread_replycut} {$thread_prefixcut} {$forumin} {$thread_usersql} {$permsql} {$visiblesql} AND ({$unapproved_where_t}) AND t.closed NOT LIKE 'moved|%' {$subject_lookin} 1381 {$limitsql} 1382 "); 1383 while($thread = $db->fetch_array($query)) 1384 { 1385 $threads[$thread['tid']] = $thread['tid']; 1386 if($thread['firstpost']) 1387 { 1388 $posts[$thread['tid']] = $thread['firstpost']; 1389 } 1390 } 1391 } 1392 1393 $query = $db->query(" 1394 SELECT p.pid, p.tid 1395 FROM ".TABLE_PREFIX."posts p 1396 LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid) 1397 WHERE 1=1 {$post_datecut} {$thread_replycut} {$thread_prefixcut} {$forumin} {$post_usersql} {$permsql} {$tidsql} {$visiblesql} {$post_visiblesql} AND ({$unapproved_where_t}) AND ({$unapproved_where_p}) AND t.closed NOT LIKE 'moved|%' {$message_lookin} 1398 {$limitsql} 1399 "); 1400 while($post = $db->fetch_array($query)) 1401 { 1402 $posts[$post['pid']] = $post['pid']; 1403 $threads[$post['tid']] = $post['tid']; 1404 } 1405 1406 if(count($posts) < 1 && count($threads) < 1) 1407 { 1408 error($lang->error_nosearchresults); 1409 } 1410 $threads = implode(',', $threads); 1411 $posts = implode(',', $posts); 1412 1413 } 1414 // Searching only thread titles 1415 else 1416 { 1417 $query = $db->query(" 1418 SELECT t.tid, t.firstpost 1419 FROM ".TABLE_PREFIX."threads t 1420 WHERE 1=1 {$thread_datecut} {$thread_replycut} {$thread_prefixcut} {$forumin} {$thread_usersql} {$permsql} {$visiblesql} AND ({$unapproved_where_t}) {$subject_lookin} 1421 {$limitsql} 1422 "); 1423 while($thread = $db->fetch_array($query)) 1424 { 1425 $threads[$thread['tid']] = $thread['tid']; 1426 if($thread['firstpost']) 1427 { 1428 $firstposts[$thread['tid']] = $thread['firstpost']; 1429 } 1430 } 1431 if(count($threads) < 1) 1432 { 1433 error($lang->error_nosearchresults); 1434 } 1435 1436 $threads = implode(',', $threads); 1437 $firstposts = implode(',', $firstposts); 1438 if($firstposts) 1439 { 1440 $query = $db->simple_select("posts", "pid", "pid IN ($firstposts) {$plain_post_visiblesql} {$limitsql}"); 1441 while($post = $db->fetch_array($query)) 1442 { 1443 $posts[$post['pid']] = $post['pid']; 1444 } 1445 $posts = implode(',', $posts); 1446 } 1447 } 1448 return array( 1449 "threads" => $threads, 1450 "posts" => $posts, 1451 "querycache" => '' 1452 ); 1453 } 1454 1455 /** 1456 * Perform a thread and post search under MySQL or MySQLi using boolean fulltext capabilities 1457 * 1458 * @param array $search Array of search data 1459 * @return array Array of search data with results mixed in 1460 */ 1461 function perform_search_mysql_ft($search) 1462 { 1463 global $mybb, $db, $lang; 1464 1465 $keywords = clean_keywords_ft($search['keywords']); 1466 1467 if($mybb->settings['minsearchword'] < 1) 1468 { 1469 $mybb->settings['minsearchword'] = 4; 1470 } 1471 1472 $message_lookin = $subject_lookin = ''; 1473 if($keywords) 1474 { 1475 $keywords_exp = explode("\"", $keywords); 1476 $inquote = false; 1477 foreach($keywords_exp as $phrase) 1478 { 1479 if(!$inquote) 1480 { 1481 $split_words = preg_split("#\s{1,}#", $phrase, -1); 1482 foreach($split_words as $word) 1483 { 1484 $word = str_replace(array("+", "-", "*"), '', $word); 1485 if(!$word) 1486 { 1487 continue; 1488 } 1489 if(my_strlen($word) < $mybb->settings['minsearchword']) 1490 { 1491 $all_too_short = true; 1492 } 1493 else 1494 { 1495 $all_too_short = false; 1496 break; 1497 } 1498 } 1499 } 1500 else 1501 { 1502 $phrase = str_replace(array("+", "-", "*"), '', $phrase); 1503 if(my_strlen($phrase) < $mybb->settings['minsearchword']) 1504 { 1505 $all_too_short = true; 1506 } 1507 else 1508 { 1509 $all_too_short = false; 1510 break; 1511 } 1512 } 1513 $inquote = !$inquote; 1514 } 1515 // Show the minimum search term error only if all search terms are too short 1516 if($all_too_short == true) 1517 { 1518 $lang->error_minsearchlength = $lang->sprintf($lang->error_minsearchlength, $mybb->settings['minsearchword']); 1519 error($lang->error_minsearchlength); 1520 } 1521 $message_lookin = "AND MATCH(message) AGAINST('".$db->escape_string($keywords)."' IN BOOLEAN MODE)"; 1522 $subject_lookin = "AND MATCH(subject) AGAINST('".$db->escape_string($keywords)."' IN BOOLEAN MODE)"; 1523 } 1524 $post_usersql = ''; 1525 $thread_usersql = ''; 1526 if(!empty($search['author'])) 1527 { 1528 $userids = array(); 1529 $search['author'] = my_strtolower($search['author']); 1530 if($search['matchusername']) 1531 { 1532 $user = get_user_by_username($search['author']); 1533 if($user) 1534 { 1535 $userids[] = $user['uid']; 1536 } 1537 } 1538 else 1539 { 1540 $query = $db->simple_select("users", "uid", "username LIKE '%".$db->escape_string_like($search['author'])."%'"); 1541 1542 while($user = $db->fetch_array($query)) 1543 { 1544 $userids[] = $user['uid']; 1545 } 1546 } 1547 1548 if(count($userids) < 1) 1549 { 1550 error($lang->error_nosearchresults); 1551 } 1552 else 1553 { 1554 $userids = implode(',', $userids); 1555 $post_usersql = " AND p.uid IN (".$userids.")"; 1556 $thread_usersql = " AND t.uid IN (".$userids.")"; 1557 } 1558 } 1559 $datecut = $thread_datecut = $post_datecut = ''; 1560 if(!empty($search['postdate'])) 1561 { 1562 if($search['pddir'] == 0) 1563 { 1564 $datecut = "<="; 1565 } 1566 else 1567 { 1568 $datecut = ">="; 1569 } 1570 $now = TIME_NOW; 1571 $datelimit = $now-(86400 * $search['postdate']); 1572 $datecut .= "'$datelimit'"; 1573 $post_datecut = " AND p.dateline $datecut"; 1574 $thread_datecut = " AND t.dateline $datecut"; 1575 } 1576 1577 $thread_replycut = ''; 1578 if(!empty($search['numreplies']) && $search['findthreadst']) 1579 { 1580 if((int)$search['findthreadst'] == 1) 1581 { 1582 $thread_replycut = " AND t.replies >= '".(int)$search['numreplies']."'"; 1583 } 1584 else 1585 { 1586 $thread_replycut = " AND t.replies <= '".(int)$search['numreplies']."'"; 1587 } 1588 } 1589 1590 $thread_prefixcut = ''; 1591 $prefixlist = array(); 1592 if(!empty($search['threadprefix']) && $search['threadprefix'][0] != 'any') 1593 { 1594 foreach($search['threadprefix'] as $threadprefix) 1595 { 1596 $threadprefix = (int)$threadprefix; 1597 $prefixlist[] = $threadprefix; 1598 } 1599 } 1600 if(count($prefixlist) == 1) 1601 { 1602 $thread_prefixcut .= " AND t.prefix='$threadprefix' "; 1603 } 1604 else 1605 { 1606 if(count($prefixlist) > 1) 1607 { 1608 $thread_prefixcut = " AND t.prefix IN (".implode(',', $prefixlist).")"; 1609 } 1610 } 1611 1612 $forumin = ''; 1613 $fidlist = array(); 1614 $searchin = array(); 1615 if(!empty($search['forums']) && (!is_array($search['forums']) || $search['forums'][0] != "all")) 1616 { 1617 if(!is_array($search['forums'])) 1618 { 1619 $search['forums'] = array((int)$search['forums']); 1620 } 1621 foreach($search['forums'] as $forum) 1622 { 1623 $forum = (int)$forum; 1624 if($forum > 0) 1625 { 1626 $fidlist[] = $forum; 1627 $child_list = get_child_list($forum); 1628 if(is_array($child_list)) 1629 { 1630 $fidlist = array_merge($fidlist, $child_list); 1631 } 1632 } 1633 } 1634 $fidlist = array_unique($fidlist); 1635 if(count($fidlist) >= 1) 1636 { 1637 $forumin = " AND t.fid IN (".implode(',', $fidlist).")"; 1638 } 1639 } 1640 $permsql = ""; 1641 $onlyusfids = array(); 1642 1643 // Check group permissions if we can't view threads not started by us 1644 $group_permissions = forum_permissions(); 1645 foreach($group_permissions as $fid => $forum_permissions) 1646 { 1647 if(isset($forum_permissions['canonlyviewownthreads']) && $forum_permissions['canonlyviewownthreads'] == 1) 1648 { 1649 $onlyusfids[] = $fid; 1650 } 1651 } 1652 if(!empty($onlyusfids)) 1653 { 1654 $permsql .= "AND ((t.fid IN(".implode(',', $onlyusfids).") AND t.uid='{$mybb->user['uid']}') OR t.fid NOT IN(".implode(',', $onlyusfids)."))"; 1655 } 1656 1657 $unsearchforums = get_unsearchable_forums(); 1658 if($unsearchforums) 1659 { 1660 $permsql .= " AND t.fid NOT IN ($unsearchforums)"; 1661 } 1662 $inactiveforums = get_inactive_forums(); 1663 if($inactiveforums) 1664 { 1665 $permsql .= " AND t.fid NOT IN ($inactiveforums)"; 1666 } 1667 1668 $visiblesql = $post_visiblesql = $plain_post_visiblesql = $unapproved_where_t = $unapproved_where_p = ""; 1669 if(isset($search['visible'])) 1670 { 1671 if($search['visible'] == 1) 1672 { 1673 $visiblesql = " AND t.visible = '1'"; 1674 1675 if($search['postthread'] == 1) 1676 { 1677 $post_visiblesql = " AND p.visible = '1'"; 1678 $plain_post_visiblesql = " AND visible = '1'"; 1679 } 1680 } 1681 elseif($search['visible'] == -1) 1682 { 1683 $visiblesql = " AND t.visible = '-1'"; 1684 1685 if($search['postthread'] == 1) 1686 { 1687 $post_visiblesql = " AND p.visible = '-1'"; 1688 $plain_post_visiblesql = " AND visible = '-1'"; 1689 } 1690 } 1691 else 1692 { 1693 $visiblesql = " AND t.visible != '1'"; 1694 1695 if($search['postthread'] == 1) 1696 { 1697 $post_visiblesql = " AND p.visible != '1'"; 1698 $plain_post_visiblesql = " AND visible != '1'"; 1699 } 1700 } 1701 } 1702 1703 // Moderators can view unapproved threads and deleted threads from forums they moderate 1704 $unapproved_where_t = get_visible_where('t'); 1705 $unapproved_where_p = get_visible_where('p'); 1706 1707 // Searching a specific thread? 1708 $tidsql = ''; 1709 if(!empty($search['tid'])) 1710 { 1711 $tidsql = " AND t.tid='".(int)$search['tid']."'"; 1712 } 1713 1714 $limitsql = ''; 1715 if((int)$mybb->settings['searchhardlimit'] > 0) 1716 { 1717 $limitsql = "LIMIT ".(int)$mybb->settings['searchhardlimit']; 1718 } 1719 1720 // Searching both posts and thread titles 1721 $threads = array(); 1722 $posts = array(); 1723 $firstposts = array(); 1724 if($search['postthread'] == 1) 1725 { 1726 // No need to search subjects when looking for results within a specific thread 1727 if(empty($search['tid'])) 1728 { 1729 $query = $db->query(" 1730 SELECT t.tid, t.firstpost 1731 FROM ".TABLE_PREFIX."threads t 1732 WHERE 1=1 {$thread_datecut} {$thread_replycut} {$thread_prefixcut} {$forumin} {$thread_usersql} {$permsql} {$visiblesql} AND ({$unapproved_where_t}) AND t.closed NOT LIKE 'moved|%' {$subject_lookin} 1733 {$limitsql} 1734 "); 1735 while($thread = $db->fetch_array($query)) 1736 { 1737 $threads[$thread['tid']] = $thread['tid']; 1738 if($thread['firstpost']) 1739 { 1740 $posts[$thread['tid']] = $thread['firstpost']; 1741 } 1742 } 1743 } 1744 1745 $query = $db->query(" 1746 SELECT p.pid, p.tid 1747 FROM ".TABLE_PREFIX."posts p 1748 LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid) 1749 WHERE 1=1 {$post_datecut} {$thread_replycut} {$thread_prefixcut} {$forumin} {$post_usersql} {$permsql} {$tidsql} {$post_visiblesql} {$visiblesql} AND ({$unapproved_where_t}) AND {$unapproved_where_p} AND t.closed NOT LIKE 'moved|%' {$message_lookin} 1750 {$limitsql} 1751 "); 1752 while($post = $db->fetch_array($query)) 1753 { 1754 $posts[$post['pid']] = $post['pid']; 1755 $threads[$post['tid']] = $post['tid']; 1756 } 1757 if(count($posts) < 1 && count($threads) < 1) 1758 { 1759 error($lang->error_nosearchresults); 1760 } 1761 $threads = implode(',', $threads); 1762 $posts = implode(',', $posts); 1763 1764 } 1765 // Searching only thread titles 1766 else 1767 { 1768 $query = $db->query(" 1769 SELECT t.tid, t.firstpost 1770 FROM ".TABLE_PREFIX."threads t 1771 WHERE 1=1 {$thread_datecut} {$thread_replycut} {$thread_prefixcut} {$forumin} {$thread_usersql} {$permsql} {$visiblesql} AND ({$unapproved_where_t}) {$subject_lookin} 1772 {$limitsql} 1773 "); 1774 while($thread = $db->fetch_array($query)) 1775 { 1776 $threads[$thread['tid']] = $thread['tid']; 1777 if($thread['firstpost']) 1778 { 1779 $firstposts[$thread['tid']] = $thread['firstpost']; 1780 } 1781 } 1782 if(count($threads) < 1) 1783 { 1784 error($lang->error_nosearchresults); 1785 } 1786 1787 $threads = implode(',', $threads); 1788 $firstposts = implode(',', $firstposts); 1789 if($firstposts) 1790 { 1791 $query = $db->simple_select("posts", "pid", "pid IN ($firstposts) {$plain_post_visiblesql} {$limitsql}"); 1792 while($post = $db->fetch_array($query)) 1793 { 1794 $posts[$post['pid']] = $post['pid']; 1795 } 1796 $posts = implode(',', $posts); 1797 } 1798 } 1799 return array( 1800 "threads" => $threads, 1801 "posts" => $posts, 1802 "querycache" => '' 1803 ); 1804 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| 2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup | Cross-referenced by PHPXref |