<?php

// "hidden" and "deleted" files are removed from the search index so we don't have to join all_search and all_files tables..

//		Question Now: How is it best to do a search restricted to a single user account? and still be able to use the full-text..
//			.. this can probably wait!

//		Advanced Search .. what does it look like
// 		The boolean full-text search capability supports the following operators:
// 		+
// 		    A leading plus sign indicates that this word must be present in every row returned. 
// 		-
// 		    A leading minus sign indicates that this word must not be present in any row returned. 
// 		    By default (when neither plus nor minus is specified) the word is optional, but the rows that contain it will be rated higher. This mimicks the behaviour of MATCH() ... AGAINST() without the IN BOOLEAN MODE modifier. 
// 		< >
// 		    These two operators are used to change a word's contribution to the relevance value that is assigned to a row. The < operator decreases the contribution and the > operator increases it. See the example below. 
// 		( )
// 		    Parentheses are used to group words into subexpressions. 
// 		~
// 		    A leading tilde acts as a negation operator, causing the word's contribution to the row relevance to be negative. It's useful for marking noise words. A row that contains such a word will be rated lower than others, but will not be excluded altogether, as it would be with the - operator. 
// 		*
// 		    An asterisk is the truncation operator. Unlike the other operators, it should be appended to the word, not prepended. 
// 		"
// 		    The phrase, that is enclosed in double quotes ", matches only rows that contain this phrase literally, as it was typed. 



defined('WikyBlog') or die("Not an entry point...");



if( !isset($GLOBALS['wbConfig']['search']) || !$GLOBALS['wbConfig']['search'] ){
	message('ENABLE_SEARCH');
	return;
}


includeFile('search/all.php');
	
class searchSearch extends query{
	var $classes;
	var $placeholder;
	var $allUsers = false;
	var $advanced = false;
	
	function searchSearch(){
		global $page,$dbInfo,$pageOwner;
		global $langA,$wbTables;
		$this->overWrite['nothing'] = false;
		
		$_GET += array('key'=>'','all'=>'','phrase'=>'','except'=>'','pre'=>'');
		
			
		//all users
			if( isset($_GET['allusers']) ){
				$this->allUsers = true;
			}
			
		$page->formAction = '/Special/'.$pageOwner['username'].'/Search?'.arrayToBrowseString($_GET);
		$searchKey = $_GET['key'];
		
		//advanced search parameters
			if( !empty($_GET['all']) ){
				$this->advanced = true;
				$temp = $this->getWords($_GET['all']);
				foreach($temp as $key){
					$searchKey .= ' +'.$key;
				}
			}
			if( !empty($_GET['phrase']) ){
				$this->advanced = true;
				$searchKey .= ' +"'.str_replace('"','',$_GET['phrase']).'"';
			}
			if( !empty($_GET['except']) ){
				$this->advanced = true;
				$temp = $this->getWords($_GET['except']);
				foreach($temp as $key){
					$searchKey .= ' -'.$key;
				}
			}
			if( !empty($_GET['pre']) ){
				$this->advanced = true;
				$temp = $this->getWords($_GET['pre']);
				foreach($temp as $key){
					$searchKey .= $key.'* ';
				}
			}

		//no need to search
			if( empty($searchKey) || !isset($_GET['search']) ){
				$page->formAction = '/Special/'.$pageOwner['username'].'/Search';
				$page->contentA[$langA['search']] = $this->advancedForm();
				return;
			}
				
		// $this->placeholder = str_shuffle('W0I1K2Y3B4L5O6G7P8L9A0C1E2H3O4L5D6E7R8');
		// $content = ' RIGHT(SUBSTR( content, 1, POSITION("'.wbDB::escape($searchKey).'" in content)+100),200) ';
		// $position = ' POSITION("'.wbDB::escape($searchKey).'" in '.$content.') ';
		// $selectText[] = ' INSERT('.$content.','.$position.',0,"'.$this->placeholder.'") as piece ';
		// $this->query = dbInfoToQuery($where,$selectText);
		// $this->orderBy();
		// $this->limit();

		//EVEN NEWER
		//The words in the search
		// $pattern = '#([a-zA-Z0-9_\']+)#S';
		// preg_match_all($pattern,$searchKey,$matches,PREG_PATTERN_ORDER);
		
		
		// message(showArray($matches[0]));
		// $howMany = min(count($matches[0]),4);
		// $length = ceil(200/$howMany);
		// $temp = array();
		// $i = 0;
		// while($i < $howMany){
		// 	$word = wbDB::escape($matches[0][$i]);
		// 	$position = ' POSITION("'.$word.'" in `all_content`) ';
		// 	$temp[] = ' RIGHT(SUBSTR( `all_content`, 1, POSITION("'.$word.'" in `all_content`)),'.$length.') ';
		// 	$i++;
		// }
		// message(implode(', ',$temp));
		
		
		
		//!!this isn't case-insensitive and doesn't work all that well!
		// $contentSql = false;
		// foreach($matches[0] as $word){
		// 	$word = wbDB::escape($word);
		// 	if( !$contentSql ){
		// 		$position = ' POSITION("'.$word.'" in `all_content`) ';
		// 		$contentSql = ' RIGHT( SUBSTRING( `all_content`, 1, POSITION("'.$word.'" in `all_content`)+50),200) ';
		// 	}
		// 	$contentSql = ' REPLACE('.$contentSql.',"'.$word.'","<b>'.$word.'</b>") ';
		// }
		// if( !$contentSql ){
		// 	$contentSql = ' "" ';
		// }
		
		$contentSql = ' SUBSTRING( `all_content`, 1, 300) ';
		

		$page->displayTitle = $langA['search:'].wbHtmlspecialchars($searchKey);
		$this->searchUrl = '/Special/'.$pageOwner['username'].'/Search';
		
		$page->css2 =true;
		$this->rowLimit = 10;
		
		//$this->fields[--shown to user--] = --database column--
		$this->fields[$langA['relevance']] = 'relevance'; //

		
		$this->selectFrom = $wbTables['all_search'].' INNER JOIN '.$wbTables['all_files'].' USING(`file_id`) ';
		$this->joinAllTo = $wbTables['all_search'];
		
		
		//could we value the title more than the content with something like this?
		//$match = ' ( MATCH(all_title) AGAINST("'.wbDB::escape($searchKey).'") + MATCH(all_title,all_content) AGAINST("'.wbDB::escape($searchKey).'")) ';
		$match = 'MATCH(all_title,all_content) AGAINST("'.wbDB::escape($searchKey).'")';
		$modified = $wbTables['all_files'].'.`modified` ';
		$this->allSelect = array($match=>'relevance',$contentSql=>'formatted',$modified=>'modified');
		
		$this->queryAllFiles();
		$this->query .= ' AND MATCH(`all_title`,`all_content`) AGAINST("'.wbDB::escape($searchKey).'" IN BOOLEAN MODE) ';
		
		//single user or all users
		if( !$this->allUsers ){
			$this->query .= ' AND '.$wbTables['all_files'].'.`owner_id` = "'.wbDB::escape($pageOwner['user_id']).'"';
		}
		
		$this->orderBy();
		$label = $langA['search:'].' '.wbHtmlspecialchars($searchKey);
		
		$this->browse($label);
	}
	
	// we only store certain characters in the all_search table
	//	so we only want to search for these characters
	function getWords(&$text){
		$pattern = '#([a-zA-Z0-9_\']+)#';
		preg_match_all($pattern,$text,$matches,PREG_PATTERN_ORDER);
		$matches[0] = array_diff($matches[0],array(null,''));
		return $matches[0];
		//return implode(' ',$matches[0]);
	}
	
	function displayEmpty(){
		parent::displayEmpty();
		echo '<p> <br/> </p>';
		echo $this->advancedForm();
		return false;
	}
	function displayPre(){}
	
	function displayPost(&$prev,&$pages,&$next,$listItems=null,$more=null){
		echo '<p> <br/> </p>';
		echo $this->advancedForm();
		parent::displayPost($prev,$pages,$next,$listItems,$more);
	}
	
	function abbrevOutput(&$row){
		global $pageOwner,$langA;
		
		
		$this->queryAllResult($row);
		
		echo '<table><tr><td style="white-space:nowrap">';
			//relevance
			//y=(1600-(x-40)^2)^(1/2) add a little arc..  0 < x < 40
			$row['relevance'] = $row['relevance']*2;
			$x = min(40,(40*$row['relevance']/100));
			$pos = pow(1600-pow($x-40,2),1/2);
			//message($x.'::'.$y);
			
			echo '<span title="'.number_format($pos,2).'%" class="wbRelevance" style="cursor:pointer">';	
			echo '<img src="'.wbLinks::getDir('/imgs/blank.gif').'" class="wbRelevancePos" alt="" align="absmiddle" border="0" height="4" width="'.ceil($pos).'">';
			echo '<img src="'.wbLinks::getDir('/imgs/blank.gif').'" class="wbRelevanceNeg" alt="" align="absmiddle" border="0" height="4" width="'.(40-ceil($pos)).'">';
			echo '</span> ';
			
		echo '</td><td>';
			
			echo '<span class="title">';
			echo wbLinks::local($row['uniqLink'],toDisplay($row['dTitle']));
			echo '</span>';
			if( $this->allUsers ){
				echo ' &nbsp; <span class="sm"> (';
				echo wbLinks::user($row['owner']);
				echo ') </span>';
			}
		echo '</td></tr>';
		echo '<tr><td></td><td>';
			
				
				echo $row['formatted'];
				
				echo '<span class="sm" style="white-space:nowrap">';
				echo ' ... [ ';
				echo wbLinks::local($row['uniqLink'].'?cmd=edit',$langA['edit']);
				echo ' ]';
				echo '</span>';
			
			
			
		echo '</td></tr></table>';
			
			
			
			
		echo ' &nbsp; <br/>';
	}
	
	
	function advancedForm(){
		global $page, $pageOwner,$langA,$jsNum;
		$page->css2 = true;
		$page->formMethod = 'get';
		$page->displayTitle = $langA['search'];
		$page->scripts[] = '/include/js/search.js?'.$jsNum;

		ob_start();

		echo '<table class="WBtoolbar" border="0" >';
		echo '<tbody>';
		echo '<tr>';
			echo '<td>'.$langA['SEARCH_ONE'].'</td>';
			echo '<td> <input type="text" name="key" value="'.wbHtmlspecialchars($_GET['key']).'" size="30" /> </td>';
			echo '<td><a href="javascript:void(0)" onclick="WB.st(this);return false;">'.$langA['advanced'].'</a></td>';
			echo '</tr>';
		echo '</tbody>';
			
		if( $this->advanced ){
			echo '<tbody>';
		}else{
			echo '<tbody style="display:none">';
		}
			
			
		echo '<tr>';
			echo '<td>'.$langA['SEARCH_ALL'].'</td>';
			echo '<td> <input type="text" name="all" value="'.wbHtmlspecialchars($_GET['all']).'" size="30" /> </td>';
			echo '</tr>';
		
		echo '<tr>';
			echo '<td>'.$langA['SEARCH_EXACT'].'</td>';
			echo '<td> <input type="text" name="phrase" value="'.wbHtmlspecialchars($_GET['phrase']).'" size="30" /> </td>';
			echo '</tr>';
			
		echo '<tr>';
			echo '<td>'.$langA['SEARCH_WITHOUT'].'</td>';
			echo '<td> <input type="text" name="except" value="'.wbHtmlspecialchars($_GET['except']).'" size="30" /> ';
			echo '</td>';
			echo '</tr>';
			
		echo '<tr>';
			echo '<td>'.$langA['SEARCH_BEGIN'].'</td>';
			echo '<td> <input type="text" name="pre" value="'.wbHtmlspecialchars($_GET['pre']).'" size="30" /> ';
			echo '</td><td>';
			echo '</td></tr>';
		echo '</tbody>';
			
		echo '<tr>';
			echo '<td></td>';
			echo '<td>';
			echo '<label>';
			if( $this->allUsers ){
				echo ' <input type="checkbox" name="allusers" value="all" checked="checked" />';
			}else{
				echo ' <input type="checkbox" name="allusers" value="all" />';
			}
			echo ' &nbsp; ';
			echo $langA['all_users'];
			echo '</label>';			
			echo '</td><td>';
			echo ' <input type="submit" name="search" value="'.$langA['search'].'" class="submit" /> ';
			echo '</td></tr>';
			
			
		echo '</table>';
		return wb::get_clean();
		
	}
}
//					searchSearch
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//					other functions
//

	// this function is in multiple files
	// similar to functions in adminConfig.php, specPreferences.php
	function formSelect($name,$values,$selected=null){
		$select = '<select name="'.$name.'">';
		foreach($values as $key => $value){
			if($key == $selected){
				$focus = ' selected ';
			}else{
				$focus = '';
			}
			if( is_numeric($key) ){
				$key = '';
			}
			$select .= '<option value="'.wbHtmlspecialchars($key).'" '.$focus.'>'.$value.'</option>';
		}
		$select .= '</select>';
		return $select;
	}
	
//					other functions
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//					Control Flow
//

global $page,$pageOwner,$dbObject,$dbObject,$langA,$pageOwner;
	
$page->regLink($langA['search'],'/Special/'.$pageOwner['username'].'/Search');
$page->regLink('?',$langA['search'].'?en=Search');


new searchSearch();