<?php
class clsAdvancedSearchResults extends clsItemCollection
{
    var $ResultTable;
    var $FieldList;
    var $FieldWeight;
    var $WhereClauses;
    var $SourceTable;
    var $Relationships;
    var $Ignored_Words;
    var $CatClause;   
    var $Keywords;
    var $Phrase = "";
    var $SearchType;
    var $RequiredRelevance;
    var $PctRelevance;
    var $PctPop;
    var $PctRating;

    function clsAdvancedSearchResults($SearchSource,$DataClass, $ItemType = 0)
    {
        global $objConfig, $objSearchConfig;

        $this->clsItemCollection();
        $this->SourceTable = $SearchSource;
        $this->SetResultTable($SearchSource,$DataClass);
        $this->FieldList = array();
        $this->Relationships = array();
        $this->Ignored_Words = array();
        $this->WhereClauses = array();
        $this->FieldWeight = array();
        $this->Keywords = GetKeywords("");
        $this->SearchType = 0; //simple
        $this->RequiredRelevance=0;
        $this->PctRelevance = $objConfig->Get("SearchRel_DefaultKeyword")/100;
        $this->PctPop = $objConfig->Get("SearchRel_DefaultPop")/100;
        $this->PctRating = $objConfig->Get("SearchRel_DefaultRating")/100;
        if(!is_object($objSearchConfig))
          $objSearchConfig = new clsSearchConfigList();
        $objSearchConfig->Clear();
        
        if ($ItemType == 0) {
        	$objSearchConfig->Query_Item("SELECT * FROM ".$objSearchConfig->SourceTable." WHERE TableName='$SearchSource' AND AdvancedSearch=1 ORDER BY DisplayOrder");  
        }
        else {
        	$tables = Array(1 => 'Category', 2 => 'News',
     							3 => 'Topic', 4 => 'Link',
     							11 => 'Products');
     		$table = $tables[$ItemType];
        	$sql = "SELECT sc.* FROM ".$objSearchConfig->SourceTable." AS sc LEFT JOIN ".GetTablePrefix()."CustomField AS cf ON sc.CustomFieldId = cf.CustomFieldId  WHERE TableName='$table' OR ((TableName='".GetTablePrefix()."CustomField' OR TableName='CustomField') AND cf.Type = $ItemType) AND AdvancedSearch=1 ORDER BY sc.DisplayOrder";
        	$objSearchConfig->Query_Item($sql);
        }
    }

    function SetResultTable($SearchSource,$DataClass)
    {
        global $objSession;

        //$this->ResultTable = $objSession->GetSessionKey()."_Search";
        $this->ResultTable = $objSession->GetSessionTable('Search', '');
        $this->classname= $DataClass;
    }

    function LoadSearchResults($Start=0,$PerPage=NULL)
    {
      if($PerPage)
      {
          $limit = "LIMIT $Start,$PerPage";
      }
      $sql = "SELECT * FROM ".$this->ResultTable." ".$limit;      
      $this->Clear();
      $rs = $this->adodbConnection->Execute($sql);
      return $this->Query_Item($sql);
    }
    
    function SetCategoryClause($whereclause)
    {
        $this->CatClause=$whereclause;
    }

    function AddRelationship($JoinTable,$JoinExpression=NULL)
    {
        $this->Relationships[$JoinTable]=$JoinExpression;        
    }

    function SetKeywords($keywords)
    {
        $this->Phrase=$keywords; 
        $this->keywords = GetKeywords($keywords);
    }

    function AddAdvancedField($TableName,$FieldName,$Verb,$Value,$conj)
    {
    	global $objSearchConfig, $objConfig;
    	
    	static $x = 0;
    	
    	if(!is_object($objSearchConfig))
    	  $objSearchConfig = new clsSeachConfigList();
    	  
       	if ($TableName==GetTablePrefix().'CustomField') 
       	{
       		$prefix = '';
       	}
       	else 
       	{
       		$prefix = GetTablePrefix();
       	}
       	$f = $prefix.$TableName.".".$FieldName;
       	$FieldConfig = $objSearchConfig->GetItemByName($TableName,$FieldName);
       	if(is_object($FieldConfig))
       	{
       	  if(strlen($FieldConfig->Get("ForeignField"))>0)
       	  {
       	  	$x++;
       	  	$parts = explode(".",$FieldConfig->Get("ForeignField"));
       	  	$Table = $parts[0];
       	  	$pseudo = 'c'.$x;
       	  	$Table = AddTablePrefix($Table);
       	  	$Field = $parts[1];
       	  	$join = $FieldConfig->Get("JoinClause");
       	  	$join = str_replace($Table, $pseudo, $join);
       	  	$join = str_replace("{ForeignTable}", $pseudo, $join);
       	  	$join = str_replace("{LocalTable}", $TableName, $join);
       	  	$join = str_replace("{Table}", AddTablePrefix($this->SourceTable), $join);
       	  	$join = '('.$join.' AND '.$pseudo.'.CustomFieldId='.$FieldConfig->Get('CustomFieldId').')';
       	  	$this->AddRelationship($Table.' AS '.$pseudo, $join);
       	  	
       	  	// for items that does not have appropriate records in CustomMetaData table
       	  	if ($Verb == 'notcontains' || $Verb == 'isnot') 
       	  	{
       	  		$or_not_null = ' OR '.$pseudo.'.'.$Field.' IS NULL';
       	  	}
       	  	else
       	  	{
       	  		$or_not_null = '';
       	  	}
       	  	
       	  	$FieldItem["where"] = str_replace('CustomMetaData', $pseudo, $FieldConfig->GetWhereClause($Verb,$Value)).$or_not_null;
       	  	$FieldItem["Field"] = $FieldConfig->Get("ForeignField");
       	  	$FieldItem["Table"] = $pseudo;
       	  	$FieldItem["conjuction"] = $conj;
       	  	$FieldItem["weight"] = $FieldConfig->Get("Priority");
       	  }
       	  else 
       	  {
       	 	$classes = Array(	'Link' 		=> '_clsLinkList',
       	 						'News' 		=> '_clsNewsList',
       	 						'Topic' 	=> '_clsTopicList',
       	 						'Category' 	=> 'clsCatList');
       	 	$list_class = $classes[$TableName];
       	 	$objList =& new $list_class();
       	  	switch ($FieldName) 
       	 	{
       	 		case 'HotItem':       	 			
       	 			$cutoff = $objList->GetHotValue();
       	 			$Value == 1 ? $not = '' : $not = 'NOT ';   
       	 			$where_clause = $FieldConfig->GetWhereClause($Verb, $Value);    	 			
       	 			$where_clause .= ' OR ('.AddTablePrefix($TableName).'.HotItem=2 AND '.
       	 							$not.'('.AddTablePrefix($TableName).
       	 							'.Hits>='.$cutoff.'))';
       	 			break;
       	 		case 'PopItem':
					$cutoff = $objList->GetPopValue();
					$Value == 1 ? $not = '' : $not = 'NOT '; 
					$where_clause = $FieldConfig->GetWhereClause($Verb, $Value);    	 			
       	 			$where_clause .= ' OR ('.AddTablePrefix($TableName).'.PopItem=2 AND '.
       	 							$not.'('.AddTablePrefix($TableName).
       	 							'.CachedRating>='.$cutoff.'))';
       	 			break;
       	 		case 'NewItem':
					$NewTime = $objConfig->Get($TableName.'_NewDays')*3600*24;
					$Value == 1 ? $not = '' : $not = 'NOT ';
					$where_clause = $FieldConfig->GetWhereClause($Verb, $Value);
					$where_clause .= ' OR ('.AddTablePrefix($TableName).'.NewItem=2 AND '.
       	 							$not.'('.mktime().'-'.AddTablePrefix($TableName).
       	 							'.CreatedOn<'.$NewTime.'))';
       	 			break;
       	 		default:   	 
		         	$where_clause = $FieldConfig->GetWhereClause($Verb, $Value);
       	 	}
       	 	$FieldItem = array();
       	 	$FieldItem['Table'] = AddTablePrefix($TableName);
       	 	$FieldItem['Field'] = $FieldName;       	 
         	$FieldItem['where'] = $FieldItem['Table'].'.'.$where_clause;
       	 	$FieldItem['conjuction'] = $conj;
       	 	$FieldItem['weight'] = $FieldConfig->Get('Priority');       	  	
       	  }
       	 $this->FieldList[] = $FieldItem;
       	 
       	 unset($FieldItem);
       }       
    }
    

/*    function AddAdvancedCustomFields()
    {
        $sql = "SELECT * FROM ".GetTablePrefix()."SearchConfig WHERE TableName='".$this->SourceTable."' AND AdvancedSearch=1 AND CustomFieldId>0";
        //echo $sql;
        foreach($this->Relationships as $Table=>$clause) 
        {
            if(strlen($Table)>0 && $Table != "Category")
              $sql .= " OR TableName='".$Table."'";
        }
        $ctable = GetTablePrefix()."CustomMetaData";
        $rs = $this->adodbConnection->Execute($sql);
        $CustomJoined = FALSE;       
        while($rs && !$rs->EOF)
        {
        	$x = $rs->fields["CustomFieldId"];
        	$t = $ctable." as c".$x;
        	$join = "(c$x.ResourceId=".GetTablePrefix().$this->SourceTable.".ResourceId AND c$x.CustomFieldId=".$rs->fields["CustomFieldId"].")";        	
        	$this->AddRelationship($t,$join);
        	$f = "c".$x.".Value ";           	
            $this->FieldList[] = $f;
            $this->FieldWeight[$f] = $rs->fields["Priority"];
            $rs->MoveNext();
        }
    }    

    function AddAdvancedFields()
    {
        $sql = "SELECT * FROM ".GetTablePrefix()."SearchConfig WHERE TableName='".$this->SourceTable."' AND AdvancedSearch=1 AND CustomFieldId=0";
        //echo $sql;
        foreach($this->Relationships as $Table=>$clause) 
        {
            if(strlen($Table)>0 && $Table != "Category")
              $sql .= " OR TableName='".$Table."'";
        }
        $rs = $this->adodbConnection->Execute($sql);
        
        while($rs && !$rs->EOF)
        {
            $f = GetTablePrefix().$rs->fields["TableName"].".".$rs->fields["FieldName"];
            $this->FieldList[] = $f;
            $this->FieldWeight[$f] = $rs->fields["Priority"];
            $rs->MoveNext();
        }
        $this->AddAdvancedCustomFields();
    }*/
    
    /* ready to write the code to build the query and go */

    function BuildWhereClause()
    {
      $where = "";  	
      foreach($this->FieldList as $f)
      	  $where .= " (".$f["where"].") ".$f["conjuction"];
      
      $cut_length = substr($where, -2) == 'OR' ? 2 : substr($where, -3) == 'AND' ? 3 : 0;
      $where = substr($where, 0, strlen($where) - $cut_length);
      return $where;
    }
    
    function PerformSearch($ItemType,$OrderBy=NULL,$InitTable=FALSE, $idlist=NULL)
    {
        static $SelectSQL, $OldItemType;
        global $objSession, $objItemTypes;
        
        $ctype = $objItemTypes->GetItem($ItemType);
        $idField = $ctype->Get("SourceTable")."Id";
        $this->SourceTable = AddTablePrefix($ctype->Get("SourceTable"));
        $result=0;
        $PopField = $ctype->Get("PopField");
        $RateField = $ctype->Get("RateField");    
        $typestr = str_pad($ItemType,2,"0",STR_PAD_LEFT);
        $SelectSQL = "SELECT ".$this->SourceTable.".".$idField." as ItemId, ". $this->SourceTable.".Priority as Relevance, ".$this->SourceTable.".ResourceId, CONCAT($typestr) as ItemType, EditorsPick as EdPick FROM ".$this->SourceTable." ";
        
        foreach($this->Relationships as $JoinTable=>$OnClause)
        {            
            $SelectSQL .= "LEFT JOIN $JoinTable ON ($OnClause) ";
        }
        $first=1;
        $WhereClause = $this->BuildWhereClause();
        if(strlen($WhereClause)>0)
        {
		    $SelectSQL .= " WHERE ".$WhereClause;
        }                  
        $SelectSQL .= " GROUP BY $idField ";
        //echo $SelectSQL;
        $this->adodbConnection->Execute("DROP TABLE IF EXISTS ".$this->ResultTable);
        $full_sql = "CREATE TABLE ".$this->ResultTable." ".$indexSQL.$SelectSQL;                 
        $this->adodbConnection->Execute($full_sql);
        // if advanced seaech used, then delete simple search keywords
        $objSession->SetVariable('Search_Keywords', '');
        //print_pre($full_sql);
    }
    
    function BuildIndexes()
    {
       $sql = "ALTER TABLE ".$this->ResultTable." ADD INDEX (Relevance), ";
       $sql .="ADD INDEX (ItemId), ";
       $sql .="ADD INDEX (ItemType), ";
       $sql .=" ADD INDEX sorting (EdPick,Relevance)";
       $this->adodbConnection->Execute($sql);
    }

    function Result_IdList()
    {
        /* returns an array contain a resource ID list */
        $sql = "SELECT DISTINCT(ResourceId) FROM ".$this->ResultTable;
        $rs = $this->adodbConnection->Execute($sql);
        $result = array();
        while($rs && !$rs->EOF)
        {
            $result[] = $rs->fields["ResourceId"];
            $rs->MoveNext();
        }
        return $result;
    }

    function SetRelevence($ItemType, $IdField)
    {
    }
}
?>