Index: trunk/kernel/include/searchitems.php =================================================================== diff -u -r604 -r642 --- trunk/kernel/include/searchitems.php (.../searchitems.php) (revision 604) +++ trunk/kernel/include/searchitems.php (.../searchitems.php) (revision 642) @@ -1,739 +1,739 @@ - : is required - - : cannot exist in the searched field - "word word" : contents between the quotes are treated as a single entity - +/-"word word" is supported - ignore words are not case sensitive -*/ -class clsSearchLog extends clsItemDB -{ - function clsSearchLog($id=NULL) - { - $this->clsItemDB(); - $this->tablename = GetTablePrefix()."SearchLog"; - $this->id_field = "SearchLogId"; - $this->NoResourceId = 1; - if($id) - $this->LoadFromDatabase($id); - } - - function LoadFromDatabase($Id) - { - global $Errors; - - if(!isset($Id)) - { - $Errors->AddError("error.AppError",NULL,'Internal error: LoadFromDatabase id',"",get_class($this),"LoadFromDatabase"); - return false; - } - $sql = sprintf("SELECT * FROM ".$this->tablename." WHERE ".$this->IdField()." = '%s'",$Id); - $result = $this->adodbConnection->Execute($sql); - if ($result === false) - { - $Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"LoadFromDatabase"); - return false; - } - - $data = $result->fields; - - $this->SetFromArray($data); - $this->Clean(); - return true; - } -} - -class clsSearchLogList extends clsItemCollection -{ - var $Page; - var $PerPageVar; - - function clsSearchLogList() - { - $this->clsItemCollection(); - $this->SourceTable = GetTablePrefix()."SearchLog"; - $this->classname = "clsSearchLog"; - $this->Page=1; - $this->PerPageVar = "Perpage_SearchLog"; - $this->AdminSearchFields = array("Keyword"); - } - - function UpdateKeyword($keyword,$SearchType) - { - $sql = "UPDATE ".$this->SourceTable." SET Indices = Indices+1 WHERE Keyword='$keyword' AND SearchType=$SearchType"; - //echo $sql."
\n"; - $this->adodbConnection->Execute($sql); - if($this->adodbConnection->Affected_Rows()==0) - { - //echo "Creating Keyword record..
\n"; - $k = new clsSearchLog(); - $k->Set("Keyword",$keyword); - $k->Set("Indices",1); - $k->Set("SearchType",$SearchType); - $k->Create(); - } - } - - function AddKeywords($Keywords) - { - if(is_array($Keywords)) - { - for($i=0;$iUpdateKeyword($Keywords[$i]); - } - } - else - $this->UpdateKeyword($Keywords); - } -} - -class clsEmailLog extends clsItemDB -{ - function clsEmailLog($id=NULL) - { - $this->clsItemDB(); - $this->tablename = GetTablePrefix()."SearchLog"; - $this->id_field = "SearchLogId"; - $this->NoResourceId = 1; - if($id) - $this->LoadFromDatabase($id); - } - - function LoadFromDatabase($Id) - { - global $Errors; - - if(!isset($Id)) - { - $Errors->AddError("error.AppError",NULL,'Internal error: LoadFromDatabase id',"",get_class($this),"LoadFromDatabase"); - return false; - } - $sql = sprintf("SELECT * FROM ".$this->tablename." WHERE ".$this->IdField()." = '%s'",$Id); - $result = $this->adodbConnection->Execute($sql); - if ($result === false) - { - $Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"LoadFromDatabase"); - return false; - } - - $data = $result->fields; - - $this->SetFromArray($data); - $this->Clean(); - return true; - } -} - -class clsEmailLogList extends clsItemCollection -{ - var $Page; - var $PerPageVar; - - function clsEmailLogList() - { - $this->clsItemCollection(); - $this->SourceTable = GetTablePrefix()."SearchLog"; - $this->classname = "clsEmailLog"; - $this->Page=1; - $this->PerPageVar = "Perpage_EmailsL"; - $this->AdminSearchFields = array("event", "fromuser", "addressto", "subject"); - } - - function UpdateKeyword($keyword,$SearchType) - { - $sql = "UPDATE ".$this->SourceTable." SET Indices = Indices+1 WHERE Keyword='$keyword' AND SearchType=$SearchType"; - //echo $sql."
\n"; - $this->adodbConnection->Execute($sql); - if($this->adodbConnection->Affected_Rows()==0) - { - //echo "Creating Keyword record..
\n"; - $k = new clsSearchLog(); - $k->Set("Keyword",$keyword); - $k->Set("Indices",1); - $k->Set("SearchType",$SearchType); - $k->Create(); - } - } - - function AddKeywords($Keywords) - { - if(is_array($Keywords)) - { - for($i=0;$iUpdateKeyword($Keywords[$i]); - } - } - else - $this->UpdateKeyword($Keywords); - } -} - -class clsSearchResults 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 clsSearchResults($SearchSource,$DataClass) - { - global $objConfig; - - $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; - } - - function SetResultTable($SearchSource,$DataClass) - { - global $objSession; - - $this->ResultTable = $objSession->GetSearchTable(); - $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 AddSimpleCustomFields() - { - $sql = "SELECT * FROM ".GetTablePrefix()."SearchConfig WHERE TableName='".$this->SourceTable."' AND SimpleSearch=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 AddSimpleFields() - { - $sql = "SELECT * FROM ".GetTablePrefix()."SearchConfig WHERE TableName='".$this->SourceTable."' AND SimpleSearch=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->AddSimpleCustomFields(); - } - - function AddSearchWhereClause($FieldName) - { - $req_where = ""; - /* build required keywords string */ - - if(count($this->keywords["required"])>0) - { - $required = $this->keywords["required"]; - for($i=0;$i0) - { - if($i>0) - { - $or =" AND "; - } - else - $or = ""; - $w .= $or." ".$FieldName." LIKE '%".$required[$i]."%'"; - } - } - if(strlen($w)>0) - { - $req_where = "(". $w.")"; - } - else - $req_where = ""; - } - $w = ""; - $not_where=""; - if(count($this->keywords["notallowed"])>0) - { - $words = $this->keywords["notallowed"]; - for($i=0;$i0) - { - if($i>0) - { - $or =" AND "; - } - else - $or = ""; - $w .= $or." ".$FieldName." NOT LIKE '%".$words[$i]."%'"; - } - } - if(strlen($w)>0) - { - $not_where = "(".$w.")"; - } - else - $not_where = ""; - } - - $w=""; - $normal = $this->keywords["normal"]; - if(count($normal)>0) - { - for($i=0;$i0) - { - if($i>0) - { - $or =" OR "; - } - else - $or = ""; - $w .= "$or $FieldName LIKE '%".$normal[$i]."%'"; - } - } - if(count($required)>0) - $w .= " OR "; - for($i=0;$i0) - { - if($i>0) - { - $or = " OR "; - } - else - $or=""; - $w .= "$or $FieldName LIKE '%".$required[$i]."%'"; - } - } - if(strlen($w)>0) - { - $where = "(".$w.")"; - } - else - $where = ""; - } - - $complete= BuildWhereClause($where,$req_where,$not_where); - $this->WhereClauses[$FieldName]="(".$complete.")"; - $this->Ignored_Words=$this->keywords["ignored"]; - } - - function PerformSearch($ItemType,$OrderBy=NULL,$InitTable=FALSE, $idlist=NULL) - { - static $SelectSQL, $OldItemType; - global $objSession, $objItemTypes; - //echo "perfirming Simple Search
"; - //echo "Old Item Type: $OldItemType New: $ItemType
\n"; - if($ItemType != $OldItemType) - $SelectSQL = ""; - $OldItemType = $ItemType; - - $ctype = $objItemTypes->GetItem($ItemType); - $idField = $ctype->Get("SourceTable")."Id"; - $this->SourceTable = GetTablePrefix().$ctype->Get("SourceTable"); - $result=0; - $PopField = $ctype->Get("PopField"); - $RateField = $ctype->Get("RateField"); - - //print_pre($this->keywords); - - if(!strlen($SelectSQL)) - { - $typestr = str_pad($ItemType,2,"0",STR_PAD_LEFT); - $SelectSQL = "SELECT "; - $ifs = array(); - $weightsum = 0; - foreach($this->FieldWeight as $w) - $weightsum += $w; - $wordcount = count($this->keywords["normal"])+count($this->keywords["required"]); - $single = ($wordcount == 1); - foreach($this->FieldList as $f) - { - $weight = (int)$this->FieldWeight[$f]; - $s = array(); - - if(!$single) - { - $full = trim(implode(" ",$this->keywords["normal"])); - $s[] = " (IF ($f LIKE '%$full%', ".$weightsum.", 0))"; - } - foreach($this->keywords["normal"] as $k) - { - if($k != $full || $single) - { - $temp = " (IF ($f LIKE '%$k%', ".$weight.", 0))"; - $s[] = $temp; - } - } - - foreach($this->keywords["required"] as $k) - { - if($this->RequiredRelevance>0) - $weight = $this->FieldWeight[$f] + ($this->FieldWeight[$f]*($this->RequiredRelevance/100)); - - if($k != $full || $single) - { - $s[] = " (IF ($f LIKE '%$k%', ".$weight.", 0))"; - } - } - // echo "
";print_r($s); echo "
"; - $txt = implode("+",$s); - //echo $txt."
\n"; - $ifs[] = $txt; - unset($s); - } -// echo "
";print_r($ifs); echo "
"; - - /* add relevance formula for weighting hits & popularity */ - - if($weightsum==0) - $weightsum=1; - - if(strlen($PopField)>0 && $this->PctPop>0) - { - $popcalc = " + ((($PopField + 1) / (max($PopField)+1)*".$this->PctPop."))"; - } - else - $popcalc = ""; - - if(strlen($RateField)>0 && $this->PctRating>0) - { - $ratecalc = " + ((($RateField + 1) / (max($RateField)+1)*".$this->PctRating."))"; - } - else - $ratecalc = ""; - - if($this->PctRelevance>0) - { - $relcalc = "(((".implode("+",$ifs).")/$weightsum)*".$this->PctRelevance.")"; - } - else - $relcalc = "0"; - - $SelectSQL .= $relcalc.$popcalc.$ratecalc." as Relevance, "; - - $SelectSQL .= $this->SourceTable.".".$idField." as ItemId, ".$this->SourceTable.".ResourceId as 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; - $where=0; - - foreach($this->FieldList as $field) - { - if(strpos($field,"as")>0) - { - $fparts = explode("as",$field,2); - $f = $fparts[1]; - $this->AddSearchWhereClause($field); - } - else { - $this->AddSearchWhereClause($field); - } - } - - $SelectSQL .= " WHERE "; - $SelectSQL .= implode(" or ",$this->WhereClauses); - - if(is_array($idlist)) - { - $SelectSQL .= " AND (ResourceId IN (".implode(",",$idlist)."))"; - } - } - $SelectSQL .= "GROUP BY $idField "; - //echo $SelectSQL."

\n"; - if($InitTable) - { - $this->adodbConnection->Execute("DROP TABLE IF EXISTS ".$this->ResultTable); - //$indexSQL = "(INDEX(Relevance), INDEX(ItemId), INDEX(ItemType), INDEX sorting (EdPick,Relevance)) "; - $full_sql = "CREATE TABLE ".$this->ResultTable." ".$indexSQL.$SelectSQL; - //echo $full_sql."
\n"; - $this->adodbConnection->Execute($full_sql); - //echo $this->adodbConnection->ErrorMsg()."
\n"; - $objSession->SetVariable("Search_Keywords",$this->Phrase); - } - else - { - $full_sql = "INSERT INTO ".$this->ResultTable." (Relevance,ItemId,ResourceId,ItemType,EdPick) ".$SelectSQL; - //echo "[".htmlspecialchars($full_sql)."]
\n"; - $this->adodbConnection->Execute($full_sql); - //echo $this->adodbConnection->ErrorMsg()."
\n"; - } - //Here we need to remove found items which was found by HTML tags matching keywords - //$this->adodbConnection->Execute("DELETE FROM ".$this->ResultTable." WHERE ItemId = 13 AND ItemType = 4"); - } - - function BuildIndexes() - { - $sql = "ALTER TABLE ".$this->ResultTable." ADD INDEX (Relevance), "; - $sql .="ADD INDEX (ItemId), "; - $sql .="ADD INDEX (ItemType), "; - $sql .=" ADD INDEX sorting (EdPick,Relevance)"; - //echo $sql; - $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 count_words($string) -{ - // below line added to make contiguous spaces count as one space - if(strlen($string)) - { - $string = eregi_replace(" +", " ", $string); - return substr_count($string," ")+1; - } - else - return 0; -} - -function GetKeywords($phrase) -{ - global $KeywordIgnore; - - if(count($KeywordIgnore)==0) - GetIgnoreList(); - $keywords["normal"]= array(); - $keywords["required"]= array(); - $keywords["notallowed"] = array(); - $keywords["ignored"] = array(); - if(!strlen($phrase)) - return $keywords; - $w_array = array(); - $phrase=trim($phrase); - //if(count_words($phrase)>1) - // $keywords["normal"][] = $phrase; - $t_len = strlen($phrase); - $ce=0; - for ($i=0; $i<$t_len; $i++) - { #search for next special tag - switch ($phrase[$i]) - { - case "\"": - $exact_match_close = strpos($phrase,"\"", $i+1); - if(!$exact_match_close) - break; - $exact_word=substr($phrase, $i+1, ($exact_match_close-$i)-1); - $i=$exact_match_close; - if($exact_word) - { - if(strlen($token)==0) - $token="|"; - $w_array[$ce]=$token.addslashes($exact_word); - $token=""; - $ce++; - $exact_word=""; - } - break; - - case "+": - if(strlen($exact_word)==0) - { - $token = "+"; - } - else - $exact_word .= "+"; - break; - case "-": - if(strlen($exact_word)==0) - { - $token = "-"; - } - else - $exact_word .="-"; - break; - case " ": - case ",": - if($exact_word) - { - if(strlen($token)==0) - $token="|"; - if($token=="|") - { - if($KeywordIgnore[strtolower($exact_word)]==1) - { - $w_array[$ce]= "=".addslashes($exact_word); - $ce++; - } - else - { - $w_array[$ce]=$token.addslashes($exact_word); - $ce++; - } - } - else - { - $w_array[$ce]=$token.addslashes($exact_word); - $ce++; - } - $token=""; - $exact_word=""; - } - break; - - default: - $exact_word.=$phrase[$i]; - } - } - if($exact_word) - { - if(strlen($token)==0) - $token="|"; - if($KeywordIgnore[strtolower($exact_word)]==1 && ($token =="|" || $token=="=")) - { - $w_array[$ce]= "=".addslashes($exact_word); - $ce++; - } - else - { - $w_array[$ce]=$token.addslashes($exact_word); - $ce++; - } - } - for ($i=0;$i0 && strlen($notallowed)>0) - { - $return .= " AND "; - } - $return .= $notallowed; - if(strlen($return)>0 && strlen($normal)>0) - { - $return .= " AND "; - } - $return .= $normal; - return $return; -} - -function GetIgnoreList() -{ - global $KeywordIgnore; - - $adodbConnection = &GetADODBConnection(); - - $rs = $adodbConnection->Execute("SELECT * FROM IgnoreKeywords"); - while($rs && !$rs->EOF) - { - $KeywordIgnore[strtolower($rs->fields["keyword"])]=1; - $rs->MoveNext(); - } -// foreach($KeywordIgnore as $word=>$dummy) -// echo $word.","; -// echo "
\n"; -} - -?> + : is required + - : cannot exist in the searched field + "word word" : contents between the quotes are treated as a single entity + +/-"word word" is supported + ignore words are not case sensitive +*/ +class clsSearchLog extends clsItemDB +{ + function clsSearchLog($id=NULL) + { + $this->clsItemDB(); + $this->tablename = GetTablePrefix()."SearchLog"; + $this->id_field = "SearchLogId"; + $this->NoResourceId = 1; + if($id) + $this->LoadFromDatabase($id); + } + + function LoadFromDatabase($Id) + { + global $Errors; + + if(!isset($Id)) + { + $Errors->AddError("error.AppError",NULL,'Internal error: LoadFromDatabase id',"",get_class($this),"LoadFromDatabase"); + return false; + } + $sql = sprintf("SELECT * FROM ".$this->tablename." WHERE ".$this->IdField()." = '%s'",$Id); + $result = $this->adodbConnection->Execute($sql); + if ($result === false) + { + $Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"LoadFromDatabase"); + return false; + } + + $data = $result->fields; + + $this->SetFromArray($data); + $this->Clean(); + return true; + } +} + +class clsSearchLogList extends clsItemCollection +{ + var $Page; + var $PerPageVar; + + function clsSearchLogList() + { + $this->clsItemCollection(); + $this->SourceTable = GetTablePrefix()."SearchLog"; + $this->classname = "clsSearchLog"; + $this->Page=1; + $this->PerPageVar = "Perpage_SearchLog"; + $this->AdminSearchFields = array("Keyword"); + } + + function UpdateKeyword($keyword,$SearchType) + { + $sql = "UPDATE ".$this->SourceTable." SET Indices = Indices+1 WHERE Keyword='$keyword' AND SearchType=$SearchType"; + //echo $sql."
\n"; + $this->adodbConnection->Execute($sql); + if($this->adodbConnection->Affected_Rows()==0) + { + //echo "Creating Keyword record..
\n"; + $k = new clsSearchLog(); + $k->Set("Keyword",$keyword); + $k->Set("Indices",1); + $k->Set("SearchType",$SearchType); + $k->Create(); + } + } + + function AddKeywords($Keywords) + { + if(is_array($Keywords)) + { + for($i=0;$iUpdateKeyword($Keywords[$i]); + } + } + else + $this->UpdateKeyword($Keywords); + } +} + +class clsEmailLog extends clsItemDB +{ + function clsEmailLog($id=NULL) + { + $this->clsItemDB(); + $this->tablename = GetTablePrefix()."SearchLog"; + $this->id_field = "SearchLogId"; + $this->NoResourceId = 1; + if($id) + $this->LoadFromDatabase($id); + } + + function LoadFromDatabase($Id) + { + global $Errors; + + if(!isset($Id)) + { + $Errors->AddError("error.AppError",NULL,'Internal error: LoadFromDatabase id',"",get_class($this),"LoadFromDatabase"); + return false; + } + $sql = sprintf("SELECT * FROM ".$this->tablename." WHERE ".$this->IdField()." = '%s'",$Id); + $result = $this->adodbConnection->Execute($sql); + if ($result === false) + { + $Errors->AddError("error.DatabaseError",NULL,$this->adodbConnection->ErrorMsg(),"",get_class($this),"LoadFromDatabase"); + return false; + } + + $data = $result->fields; + + $this->SetFromArray($data); + $this->Clean(); + return true; + } +} + +class clsEmailLogList extends clsItemCollection +{ + var $Page; + var $PerPageVar; + + function clsEmailLogList() + { + $this->clsItemCollection(); + $this->SourceTable = GetTablePrefix()."SearchLog"; + $this->classname = "clsEmailLog"; + $this->Page=1; + $this->PerPageVar = "Perpage_EmailsL"; + $this->AdminSearchFields = array("event", "fromuser", "addressto", "subject"); + } + + function UpdateKeyword($keyword,$SearchType) + { + $sql = "UPDATE ".$this->SourceTable." SET Indices = Indices+1 WHERE Keyword='$keyword' AND SearchType=$SearchType"; + //echo $sql."
\n"; + $this->adodbConnection->Execute($sql); + if($this->adodbConnection->Affected_Rows()==0) + { + //echo "Creating Keyword record..
\n"; + $k = new clsSearchLog(); + $k->Set("Keyword",$keyword); + $k->Set("Indices",1); + $k->Set("SearchType",$SearchType); + $k->Create(); + } + } + + function AddKeywords($Keywords) + { + if(is_array($Keywords)) + { + for($i=0;$iUpdateKeyword($Keywords[$i]); + } + } + else + $this->UpdateKeyword($Keywords); + } +} + +class clsSearchResults 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 clsSearchResults($SearchSource,$DataClass) + { + global $objConfig; + + $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; + } + + function SetResultTable($SearchSource,$DataClass) + { + global $objSession; + + $this->ResultTable = $objSession->GetSearchTable(); + $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 AddSimpleCustomFields() + { + $sql = "SELECT * FROM ".GetTablePrefix()."SearchConfig WHERE TableName='".$this->SourceTable."' AND SimpleSearch=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 AddSimpleFields() + { + $sql = "SELECT * FROM ".GetTablePrefix()."SearchConfig WHERE TableName='".$this->SourceTable."' AND SimpleSearch=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->AddSimpleCustomFields(); + } + + function AddSearchWhereClause($FieldName) + { + $req_where = ""; + /* build required keywords string */ + + if(count($this->keywords["required"])>0) + { + $required = $this->keywords["required"]; + for($i=0;$i0) + { + if($i>0) + { + $or =" AND "; + } + else + $or = ""; + $w .= $or." ".$FieldName." LIKE '%".$required[$i]."%'"; + } + } + if(strlen($w)>0) + { + $req_where = "(". $w.")"; + } + else + $req_where = ""; + } + $w = ""; + $not_where=""; + if(count($this->keywords["notallowed"])>0) + { + $words = $this->keywords["notallowed"]; + for($i=0;$i0) + { + if($i>0) + { + $or =" AND "; + } + else + $or = ""; + $w .= $or." ".$FieldName." NOT LIKE '%".$words[$i]."%'"; + } + } + if(strlen($w)>0) + { + $not_where = "(".$w.")"; + } + else + $not_where = ""; + } + + $w=""; + $normal = $this->keywords["normal"]; + if(count($normal)>0) + { + for($i=0;$i0) + { + if($i>0) + { + $or =" OR "; + } + else + $or = ""; + $w .= "$or $FieldName LIKE '%".$normal[$i]."%'"; + } + } + if(count($required)>0) + $w .= " OR "; + for($i=0;$i0) + { + if($i>0) + { + $or = " OR "; + } + else + $or=""; + $w .= "$or $FieldName LIKE '%".$required[$i]."%'"; + } + } + if(strlen($w)>0) + { + $where = "(".$w.")"; + } + else + $where = ""; + } + + $complete= BuildWhereClause($where,$req_where,$not_where); + $this->WhereClauses[$FieldName]="(".$complete.")"; + $this->Ignored_Words=$this->keywords["ignored"]; + } + + function PerformSearch($ItemType,$OrderBy=NULL,$InitTable=FALSE, $idlist=NULL) + { + static $SelectSQL, $OldItemType; + global $objSession, $objItemTypes; + //echo "perfirming Simple Search
"; + //echo "Old Item Type: $OldItemType New: $ItemType
\n"; + if($ItemType != $OldItemType) + $SelectSQL = ""; + $OldItemType = $ItemType; + + $ctype = $objItemTypes->GetItem($ItemType); + $idField = $ctype->Get("SourceTable")."Id"; + $this->SourceTable = GetTablePrefix().$ctype->Get("SourceTable"); + $result=0; + $PopField = $ctype->Get("PopField"); + $RateField = $ctype->Get("RateField"); + + //print_pre($this->keywords); + + if(!strlen($SelectSQL)) + { + $typestr = str_pad($ItemType,2,"0",STR_PAD_LEFT); + $SelectSQL = "SELECT "; + $ifs = array(); + $weightsum = 0; + foreach($this->FieldWeight as $w) + $weightsum += $w; + $wordcount = count($this->keywords["normal"])+count($this->keywords["required"]); + $single = ($wordcount == 1); + foreach($this->FieldList as $f) + { + $weight = (int)$this->FieldWeight[$f]; + $s = array(); + + if(!$single) + { + $full = trim(implode(" ",$this->keywords["normal"])); + $s[] = " (IF ($f LIKE '%$full%', ".$weightsum.", 0))"; + } + foreach($this->keywords["normal"] as $k) + { + if($k != $full || $single) + { + $temp = " (IF ($f LIKE '%$k%', ".$weight.", 0))"; + $s[] = $temp; + } + } + + foreach($this->keywords["required"] as $k) + { + if($this->RequiredRelevance>0) + $weight = $this->FieldWeight[$f] + ($this->FieldWeight[$f]*($this->RequiredRelevance/100)); + + if($k != $full || $single) + { + $s[] = " (IF ($f LIKE '%$k%', ".$weight.", 0))"; + } + } + // echo "
";print_r($s); echo "
"; + $txt = implode("+",$s); + //echo $txt."
\n"; + $ifs[] = $txt; + unset($s); + } +// echo "
";print_r($ifs); echo "
"; + + /* add relevance formula for weighting hits & popularity */ + + if($weightsum==0) + $weightsum=1; + + if(strlen($PopField)>0 && $this->PctPop>0) + { + $popcalc = " + ((($PopField + 1) / (max($PopField)+1)*".$this->PctPop."))"; + } + else + $popcalc = ""; + + if(strlen($RateField)>0 && $this->PctRating>0) + { + $ratecalc = " + ((($RateField + 1) / (max($RateField)+1)*".$this->PctRating."))"; + } + else + $ratecalc = ""; + + if($this->PctRelevance>0) + { + $relcalc = "(((".implode("+",$ifs).")/$weightsum)*".$this->PctRelevance.")"; + } + else + $relcalc = "0"; + + $SelectSQL .= $relcalc.$popcalc.$ratecalc." as Relevance, "; + + $SelectSQL .= $this->SourceTable.".".$idField." as ItemId, ".$this->SourceTable.".ResourceId as 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; + $where=0; + + foreach($this->FieldList as $field) + { + if(strpos($field,"as")>0) + { + $fparts = explode("as",$field,2); + $f = $fparts[1]; + $this->AddSearchWhereClause($field); + } + else { + $this->AddSearchWhereClause($field); + } + } + + $SelectSQL .= " WHERE "; + $SelectSQL .= implode(" or ",$this->WhereClauses); + + if(is_array($idlist)) + { + $SelectSQL .= " AND (ResourceId IN (".implode(",",$idlist)."))"; + } + } + $SelectSQL .= "GROUP BY $idField "; + //echo $SelectSQL."

\n"; + if($InitTable) + { + $this->adodbConnection->Execute("DROP TABLE IF EXISTS ".$this->ResultTable); + //$indexSQL = "(INDEX(Relevance), INDEX(ItemId), INDEX(ItemType), INDEX sorting (EdPick,Relevance)) "; + $full_sql = "CREATE TABLE ".$this->ResultTable." ".$indexSQL.$SelectSQL; + //echo $full_sql."
\n"; + $this->adodbConnection->Execute($full_sql); + //echo $this->adodbConnection->ErrorMsg()."
\n"; + $objSession->SetVariable("Search_Keywords",$this->Phrase); + } + else + { + $full_sql = "INSERT INTO ".$this->ResultTable." (Relevance,ItemId,ResourceId,ItemType,EdPick) ".$SelectSQL; + //echo "[".htmlspecialchars($full_sql)."]
\n"; + $this->adodbConnection->Execute($full_sql); + //echo $this->adodbConnection->ErrorMsg()."
\n"; + } + //Here we need to remove found items which was found by HTML tags matching keywords + //$this->adodbConnection->Execute("DELETE FROM ".$this->ResultTable." WHERE ItemId = 13 AND ItemType = 4"); + } + + function BuildIndexes() + { + $sql = "ALTER TABLE ".$this->ResultTable." ADD INDEX (Relevance), "; + $sql .="ADD INDEX (ItemId), "; + $sql .="ADD INDEX (ItemType), "; + $sql .=" ADD INDEX sorting (EdPick,Relevance)"; + //echo $sql; + $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 count_words($string) +{ + // below line added to make contiguous spaces count as one space + if(strlen($string)) + { + $string = eregi_replace(" +", " ", $string); + return substr_count($string," ")+1; + } + else + return 0; +} + +function GetKeywords($phrase) +{ + global $KeywordIgnore; + + if(count($KeywordIgnore)==0) + GetIgnoreList(); + $keywords["normal"]= array(); + $keywords["required"]= array(); + $keywords["notallowed"] = array(); + $keywords["ignored"] = array(); + if(!strlen($phrase)) + return $keywords; + $w_array = array(); + $phrase=trim($phrase); + //if(count_words($phrase)>1) + // $keywords["normal"][] = $phrase; + $t_len = strlen($phrase); + $ce=0; + for ($i=0; $i<$t_len; $i++) + { #search for next special tag + switch ($phrase[$i]) + { + case "\"": + $exact_match_close = strpos($phrase,"\"", $i+1); + if(!$exact_match_close) + break; + $exact_word=substr($phrase, $i+1, ($exact_match_close-$i)-1); + $i=$exact_match_close; + if($exact_word) + { + if(strlen($token)==0) + $token="|"; + $w_array[$ce]=$token.addslashes($exact_word); + $token=""; + $ce++; + $exact_word=""; + } + break; + + case "+": + if(strlen($exact_word)==0) + { + $token = "+"; + } + else + $exact_word .= "+"; + break; + case "-": + if(strlen($exact_word)==0) + { + $token = "-"; + } + else + $exact_word .="-"; + break; + case " ": + case ",": + if($exact_word) + { + if(strlen($token)==0) + $token="|"; + if($token=="|") + { + if($KeywordIgnore[strtolower($exact_word)]==1) + { + $w_array[$ce]= "=".addslashes($exact_word); + $ce++; + } + else + { + $w_array[$ce]=$token.addslashes($exact_word); + $ce++; + } + } + else + { + $w_array[$ce]=$token.addslashes($exact_word); + $ce++; + } + $token=""; + $exact_word=""; + } + break; + + default: + $exact_word.=$phrase[$i]; + } + } + if($exact_word) + { + if(strlen($token)==0) + $token="|"; + if($KeywordIgnore[strtolower($exact_word)]==1 && ($token =="|" || $token=="=")) + { + $w_array[$ce]= "=".addslashes($exact_word); + $ce++; + } + else + { + $w_array[$ce]=$token.addslashes($exact_word); + $ce++; + } + } + for ($i=0;$i0 && strlen($notallowed)>0) + { + $return .= " AND "; + } + $return .= $notallowed; + if(strlen($return)>0 && strlen($normal)>0) + { + $return .= " AND "; + } + $return .= $normal; + return $return; +} + +function GetIgnoreList() +{ + global $KeywordIgnore; + + $adodbConnection = &GetADODBConnection(); + + $rs = $adodbConnection->Execute("SELECT * FROM ".GetTablePrefix()."IgnoreKeywords"); + while($rs && !$rs->EOF) + { + $KeywordIgnore[strtolower($rs->fields["keyword"])]=1; + $rs->MoveNext(); + } +// foreach($KeywordIgnore as $word=>$dummy) +// echo $word.","; +// echo "
\n"; +} + +?>