Index: trunk/kernel/include/searchitems.php =================================================================== diff -u -r667 -r676 --- trunk/kernel/include/searchitems.php (.../searchitems.php) (revision 667) +++ trunk/kernel/include/searchitems.php (.../searchitems.php) (revision 676) @@ -1,1477 +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 ".GetTablePrefix()."IgnoreKeywords"); - while($rs && !$rs->EOF) - { - $KeywordIgnore[strtolower($rs->fields["keyword"])]=1; - $rs->MoveNext(); - } - // foreach($KeywordIgnore as $word=>$dummy) - // echo $word.","; - // echo "
\n"; - } - - ?> \ No newline at end of file