num_queries queries";}
}
function SSinput($name,$default="",$offset=0) {
global $SuperSearch, $SSrequest;
if ($name=='forums') {echo ' '.super_search_forum_list(); return;}
if ($name=='simple') {
echo '
'.(($SSrequest['advanced']) ? "Simple Search" : "Advanced Search").'';
return;
}
if (!isset($SuperSearch[$name])) {return;}
$output=""; // get ready to build resulting field
$options=count($SuperSearch[$name])-5; // are there multiple options?
$array=($options && ($SuperSearch[$name][1]=="checkbox" || strpos($SuperSearch[$name][2],"multiple"))) ? '[]' : '';
// label before item, if any, except checkboxes
if ($offset==0 && $SuperSearch[$name][0] && $SuperSearch[$name][1]!="checkbox") {$output="".__($SuperSearch[$name][0]).": ";}
if (in_array($SuperSearch[$name][1],array("text","submit","reset","checkbox","radio","hidden"))) {
$output.="";
$output.= '';}
$output.='";
if ($offset>=$options) {$output.=" ";} // write option labels and close select if last one
} else {
if ($label && $label!=$value) {$output.=">".$label;}
else {$output.=">";}
// label after item, if any, only for checkboxes
if ($offset==0 && $SuperSearch[$name][0] && $SuperSearch[$name][1]=="checkbox") {$output.="".__($SuperSearch[$name][0])." ";}
$output.=" ";
}
echo $output;
}
// recursive for other radio/checkbox options
if ($offset==0 && $label && $options>0) {
for ($i=1; $i<=$options; $i++) {
SSinput($name,"",$i);
}
}
}
function super_search_forum_list( $args = '' ) {
global $forum_id, $forum, $SuperSearch, $SSrequest;
$old_global = $forum;
$defaults = array(
'size'=>5,
'callback' => false,
'callback_args' => false,
name=> 'forums',
'id' => 'SSforums',
'tab' => 5,
'hierarchical' => 1,
'depth' => 0,
'child_of' => 0,
'disable_categories' => 1
);
if ( $args && is_string($args) && false === strpos($args, '=') ) {$args = array( 'callback' => $args );}
if ( 1 < func_num_args() ) {$args['callback_args'] = func_get_arg(1);}
$args = wp_parse_args( $args, $defaults ); extract($args, EXTR_SKIP); if ( !bb_forums( $args ) ) {return;}
// $SuperSearch['forums']=array('','select',' id="SSforums" style="width:150px" ','0','0|- Search All Forums -');
$selected=array_flip((array) explode(",",$SSrequest['forums']));
$option_selected = isset($selected[0]) ? ' selected="selected"' : '';
$r = '' . "\n";
return $r;
}
function super_search_find($ss) {
global $bbdb, $page, $topics, $topic, $posts, $total, $SSdebug,$SSwords,$SSrequest;
// todo:
// give admin option to limit number of words/phrases to search for
// limit searches per minute and/or based on system load
$search=""; $SSwords=array();
if ($SSrequest['case']) {
$result=$bbdb->get_results("SHOW VARIABLES LIKE 'collation_connection'");
$bin=$result[0]->Value."_";
$bin=substr($bin,0,strpos($bin,'_'))."_bin";
$COLLATE=" COLLATE $bin ";
} else {$COLLATE="";}
if ($SSrequest['regex']) {
$length=strlen(preg_replace('/[^a-zA-Z0-9\']/', '', $ss));
if ($length>3) {
$search=$plain=$ss; $search=addslashes($search);
$search=" ((post_text $COLLATE REGEXP '$search')) ";
}
} else {
$search=" ".stripslashes($ss)." ";
// $search=preg_replace('/[^a-zA-Z0-9-\s\*\+\-\'\"]/', '', $search); // strip punctuation - todo: check for regex option and leave alone, also: foreign languages?
preg_match_all('/( AND | NOT | OR | \+| \-|)"([^"]+?)"/smU',$search, $phrases); // [0]=full match [1]=prefix [2]=phrases without quotes
$search=str_replace($phrases[0],'',$search); // 2nd pass for words (1st grabs phrases only)
preg_match_all('/( AND | NOT | OR | \+| \-|)([^ ]+?)/smU',$search, $words);
$search=""; // init build search query
for ($p=0; $p<2; $p++) { // 1st pass phrases, 2nd pass words (I can't figure out a fast/safe way to merge the two arrays)
if ($p==0) {$pass=$phrases;} else {$pass=$words;}
// echo "
$p: ";print_r($pass); echo "
";
for ($i=0; $i2 || $operator) { // exclude words under 3 characters unless an operator is specifically stated to force it
if (substr($term,-1)=="*") {$term=substr($term,0,-1); $wildcard=true;} else {$wildcard=false;}
// if ($search) {$search.=str_replace(array("-","NOT","+","AND","OR"),array("AND NOT","AND NOT","AND","AND","OR"),$operator);} // there is an inherit problem with OR needing to track the search before it - must fix
if ($search) {$search.=($operator=="OR") ? " OR " : " AND ";} // there is an inherit problem with OR needing to track the search before it - must fix
$NOT=(in_array($operator,array("NOT","-"))) ? " NOT " : "";
$search.=" (post_text $COLLATE$NOT LIKE '%".$term."%'";
if (!empty($wildcard) || empty($SSrequest['exact'])) {$search.=") ";}
else {$search.=" AND post_text $NOT REGEXP '[[:<:]]".$term."[[:>:]][^\']') ";} // two-pass query to speed up eliminating partial words
if (empty($NOT)) {$SSwords[]=$term;}
if ($operator=="OR") {$search="($search)";}
}
} // end loop through terms
} // end loop through passes
// $plain=preg_replace("/[^a-z0-9*\'\" ]+?/i","",preg_replace("/\(?post\_text[ ]+(".$COLLATE."[ ]+)?((NOT[ ]+)?LIKE[ ]+\'\%(.+?)\%\'\))?((AND[ ]+)?(NOT[ ]+)?(REGEXP[ ]+\'.+?\'[ ]+))?/","$3$4",$search));
// $plain=preg_replace("/[^a-z0-9*\'\" ]+?/i","",preg_replace("/\(?post\_text[ ]+(".$COLLATE."[ ]+)?((NOT[ ]+)?LIKE[ ]+\'\%(.+?)\%\'\))?((AND[ ]+)?(NOT[ ]+)?(REGEXP[ ]+\'.+?\'[ ]+))?/","$3$4",$search));
$plain=$search;
if ($COLLATE) {$plain=preg_replace("/$COLLATE/","",$plain);}
$plain=preg_replace("/post\_text[ ]+/","",$plain);
$plain=preg_replace("/LIKE[ ]+\'\%(.+?)\%\'/"," $1 ",$plain);
$plain=preg_replace("/AND[ ](NOT[ ]+)?+REGEXP[ ]+\'.+?\'\)/","",$plain);
// $plain=preg_replace("/[^a-z0-9*\'\" ]+?/i","",$plain); // punctuation cleanup
$plain=stripslashes(preg_replace("/[\(\)]+?/i","",$plain));
} // end regex check
echo '
'.__('Search for').': '.wp_specialchars($plain).'
';
if (!empty($search)) {
// calculate date range
if ($SSrequest['age']<9999) {
$gmt_offset=intval(bb_get_option("gmt_offset"))*3600;
$time=strtotime(gmdate('Y-m-d',time()+$gmt_offset)." 23:59:59 +0000")-$gmt_offset; // midnight of today's date in GMT (before offset)
$time=$time-($SSrequest['age']+2)*3600*24;
$mysql_date=gmdate("Y-m-d H:i:s",$time); // store mysql search range
$direction=empty($SSrequest['direction']) ? ">=" : "<=";
$search="($search) AND post_time$direction'$mysql_date' ";
}
// array('Located','select','','0','0|anywhere in topic','1|started topic','2|replied to topic','3|only in titles','4|only in posts');
if (empty($SSrequest['located']) || $SSrequest['located']==3) {$union=str_replace(array("post_text","post_time"),array("topic_title","topic_time"),$search);}
if ($SSrequest['located']==1) {$search="($search) AND (post_position=1)";}
if ($SSrequest['located']==2) {$search="($search) AND (post_position>1)";}
if ($SSrequest['located']==3) {$search="";}
$where = str_replace(array("forum_id","topic_id"),array("$bbdb->topics.forum_id","$bbdb->topics.topic_id"),apply_filters('get_latest_topics_where',"WHERE topic_status=0 "));
if (!empty($SSrequest['forums'])) {
$where.=" AND $bbdb->topics.forum_id IN (".$SSrequest['forums'].") ";
}
$limit = bb_get_option('page_topics'); if ($SSrequest['maxcount'] <$limit) {$limit=$SSrequest['maxcount'];}
$page = $page ? intval($page) : 1;
$offset = ($page-1)*$limit;
if (!empty($search)) {
$query="SELECT
$bbdb->topics.topic_id as topic_id,topic_title,topic_slug,topic_poster,topic_poster_name,topic_last_poster,topic_last_poster_name,
topic_start_time,topic_time,$bbdb->topics.forum_id as forum_id,topic_status,topic_open,topic_last_post_id,topic_sticky,topic_posts,tag_count,
post_id,poster_id,post_text,post_time,poster_ip,post_status,post_position
FROM $bbdb->topics ";
$query.=" LEFT JOIN $bbdb->posts ON $bbdb->topics.topic_id = $bbdb->posts.topic_id ";
$query.=" $where ";
$query.=" AND post_status=0 ";
if (!empty($SSrequest['users'])) {
$query.=" AND poster_id=".$SSrequest['users'];
}
$query.=" AND ($search) ";
if (!empty($union)) {$query.=" UNION ";}
}
if (!empty($union)) {
$query.="SELECT
$bbdb->topics.topic_id as topic_id,topic_title,topic_slug,topic_poster,topic_poster_name,topic_last_poster,topic_last_poster_name,
topic_start_time,topic_time,$bbdb->topics.forum_id as forum_id,topic_status,topic_open,topic_last_post_id,topic_sticky,topic_posts,tag_count,
NULL as post_id,NULL as poster_id,NULL as post_text,NULL as post_time,NULL as poster_ip,NULL as post_status,NULL as post_position
FROM $bbdb->topics ";
$query.=" $where ";
if (!empty($SSrequest['users']) && $SSrequest['located']==1) {
$query.=" AND topic_poster=".$SSrequest['users'];
}
$query.=" AND ($union) ";
// if (!empty($search)) {$query.=" AND topic_id NOT IN (t1.$bbdb->topics.topic_id) ";}
}
/*
,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
,NULL as post_id,NULL as $bbdb->posts.forum_id,NULL as $bbdb->posts.topic_id,NULL as poster_id,
NULL as post_text,NULL as post_time,NULL as poster_ip,NULL as post_status,NULL as post_position
*/
$query="($query) as t3 ";
if ($SSrequest['sort']=='views' && function_exists('get_view_count')) {
if (defined('BACKPRESS_PATH')) {
$query.=" LEFT JOIN $bbdb->meta ON t3.topic_id=$bbdb->meta.object_id AND $bbdb->meta.object_type='bb_topic' AND $bbdb->meta.meta_key='views' ";
} else {
$query.=" LEFT JOIN $bbdb->topicmeta ON t3.topic_id=$bbdb->topicmeta.topic_id AND $bbdb->topicmeta.meta_key='views' ";
}
}
if (!empty($SSrequest['users'])) {
$query.=" WHERE poster_id=".$SSrequest['users'];
}
// combine topics if show posts turned off
if (empty($SSrequest['posts'])) {$query.=" GROUP BY t3.topic_id ";}
// 'Sort By 'date','date|Date','views|Views','posts|Posts','title|Title','user|User'
$sort=""; $restrict="";
if ($SSrequest['sort']=='date') {$sort="cast(t3.topic_id as UNSIGNED)";} // topic_start_time
elseif ($SSrequest['sort']=='freshness') {$sort="topic_time";}
elseif ($SSrequest['sort']=='posts') {$sort="topic_posts";}
elseif ($SSrequest['sort']=='title') {$sort="topic_title";}
elseif ($SSrequest['sort']=='user') {$sort="poster_id";}
$restrict.=" ORDER BY $sort ";
// sort direction
if (empty($SSrequest['order'])) {$restrict.=" DESC ";} else {$restrict.=" ASC ";}
// result count and page offset
$restrict.=" LIMIT $limit OFFSET $offset ";
if ($SSdebug) {echo "query: $query$restrict "; $bbdb->show_errors();}
$total = $bbdb->get_results("SELECT count(*) as count FROM ".$query); // bb_count_last_query(); // count($topics);
$count=count($total); if ($count==1) {$total=$total[0]->count;} else {$total=$count;}
if (empty($total)) {$total=0; $topics="";} // nothing found (perhaps search for plural or singular)
else {
if ($SSrequest['maxcount'] <$total) {$total=$SSrequest['maxcount'];}
$topics = $bbdb->get_results("SELECT * FROM ".$query.$restrict);
if ($SSdebug) {echo "
"; print_r($topics); print "
";}
// $topics = bb_append_meta( $topics, 'topic' );
// nasty, nasty workaround for multiple same id's in bb_append_meta
$trans = array(); foreach (array_keys($topics) as $i ) {$trans[$topics[$i]->topic_id]->topic_id = $topics[$i]->topic_id;}
// $trans = bb_append_meta( $trans, 'topic' ); // this doesn't work quite right when the same topic_id shows up multiple times in a list, workaround
// Fine. here's how to build it.
$ids = join(',', array_map('intval', array_keys($trans)));
if (defined('BACKPRESS_PATH')) {
$metas = $bbdb->get_results("SELECT object_id as topic_id, meta_key, meta_value FROM $bbdb->meta WHERE object_type='bb_topic' AND object_id IN ($ids)");
} else {
$metas = $bbdb->get_results("SELECT topic_id, meta_key, meta_value FROM $bbdb->topicmeta WHERE topic_id IN ($ids)");
}
if ($metas) {
foreach ( $metas as $meta ) {
$trans[$meta->topic_id]->{$meta->meta_key} = bb_maybe_unserialize( $meta->meta_value );
if ( strpos($meta->meta_key, $bbdb->prefix) === 0 )
$trans[$meta->topic_id]->{substr($meta->meta_key, strlen($bbdb->prefix))} = bb_maybe_unserialize( $meta->meta_value );
}
}
unset($metas); // cleanup
// load up the bbpress caches so template functions don't generate runaway queries
if (defined('BACKPRESS_PATH')) {$bb10=true;} else {global $bb_topic_cache,$bb_post_cache; $bb10=false;}
foreach ( array_keys($topics) as $i ) {
foreach($trans[$topics[$i]->topic_id] as $key=>$value) {$topics[$i]->$key=$value;}
if ($bb10) {wp_cache_set($topics[$i]->topic_id, $topics[$i], 'bb_topic' ); wp_cache_set($topics[$i]->post_id, $topics[$i], 'bb_post' );}
else {$bb_topic_cache[$topics[$i]->topic_id]=$topics[$i]; $bb_post_cache[$topics[$i]->post_id]=$topics[$i];}
$user_ids[$topics[$i]->poster_id]=$topics[$i]->poster_id;
$user_ids[$topics[$i]->topic_poster]=$topics[$i]->topic_poster;
$user_ids[$topics[$i]->topic_last_poster]=$topics[$i]->topic_last_poster;
}
unset($trans); // cleanup
bb_cache_users($user_ids);
// unset($topics); // this is bad, if we can't unset $topics, it's using double the memory for cache+$topics
// print_r($topics);
}
} // end test for $search
}
function super_search_show_context($text ) {
global $SSrequest, $SSwords;
$text = strip_tags($text);
$term = preg_quote($SSwords[0]);
if (!empty($SSrequest['exact'])) {$term1="\b$term\b";} else {$term1="$term";}
$offset=intval((320-strlen($term1))/2);
$text = preg_replace("|.*?(.{0,$offset})($term1)(.{0,$offset}).*|is", "... $1$2$3 ...", $text, 1);
return $text;
}
function super_search_highlight($text ) {
global $SSrequest, $SSwords;
if (!empty($SSrequest['highlight'])) {
foreach ($SSwords as $key=>$word) {
$word=preg_quote($word);
if (!empty($SSrequest['exact'])) {$term="\b$word\b";} else {$term=$word;}
$highlight="$1";
$text = preg_replace("|($term)|is", $highlight, $text, 1);
}
}
return $text;
}
function super_search_users() { // ajax helper
if (bb_current_user_can( 'participate' )) { // only let logged in users see/select specific usernames
global $bbdb;
$active = $bbdb->get_results("SELECT user_id FROM $bbdb->usermeta WHERE meta_key='bb_capabilities' and meta_value NOT REGEXP 'inactive|blocked' LIMIT 3000");
foreach (array_keys($active) as $i) {$trans[$active[$i]->user_id] =& $active[$i];}
unset($active); // huge query, release memory
$ids = join(',', array_keys($trans)); // this eventually needs to be enhanced to filter/split the array for pagination - could get HUGE
$users = $bbdb->get_results("SELECT ID,user_login FROM $bbdb->users WHERE user_status = 0 AND ID IN ($ids) ORDER BY user_login ASC LIMIT 3000");
foreach ($users as $user) {
echo "z($user->ID,'".addslashes(substr($user->user_login,0,15))."');";
}
}
exit;
}
function super_search_add_header() {
global $SSrequest;
echo '
';
}
?>