public function searchTitle($phrase = "", $nTopCount = 5, $arParams = array(), $bNotFilter = false, $order = "") { $DB = CDatabase::GetModuleConnection('search'); $bOrderByRank = $order == "rank"; $sqlHaving = array(); $sqlWords = array(); if (!empty($this->_arPhrase)) { $last = true; foreach (array_reverse($this->_arPhrase, true) as $word => $pos) { if ($last && !preg_match("/[\\n\\r \\t]\$/", $phrase)) { $last = false; if (strlen($word) >= $this->minLength) { $s = $sqlWords[] = "ct.WORD like '" . $DB->ForSQL($word) . "%'"; } else { $s = ""; } } else { $s = $sqlWords[] = "ct.WORD = '" . $DB->ForSQL($word) . "'"; } if ($s) { $sqlHaving[] = "(sum(" . $s . ") > 0)"; } } } if (!empty($sqlWords)) { $bIncSites = false; $strSqlWhere = CSearch::__PrepareFilter($arParams, $bIncSites); if ($bNotFilter) { if (!empty($strSqlWhere)) { $strSqlWhere = "NOT (" . $strSqlWhere . ")"; } else { $strSqlWhere = "1=0"; } } $strSql = "\n\t\t\t\tSELECT\n\t\t\t\t\tsc.ID\n\t\t\t\t\t,sc.MODULE_ID\n\t\t\t\t\t,sc.ITEM_ID\n\t\t\t\t\t,sc.TITLE\n\t\t\t\t\t,sc.PARAM1\n\t\t\t\t\t,sc.PARAM2\n\t\t\t\t\t,sc.DATE_CHANGE\n\t\t\t\t\t,L.DIR\n\t\t\t\t\t,L.SERVER_NAME\n\t\t\t\t\t,sc.URL as URL\n\t\t\t\t\t,scsite.URL as SITE_URL\n\t\t\t\t\t,scsite.SITE_ID\n\t\t\t\t\t,if(locate('" . $DB->ForSQL(ToUpper($phrase)) . "', upper(sc.TITLE)) > 0, 1, 0) RANK1\n\t\t\t\t\t,count(1) RANK2\n\t\t\t\t\t,min(ct.POS) RANK3\n\t\t\t\tFROM\n\t\t\t\t\tb_search_content_title ct\n\t\t\t\t\tINNER JOIN b_lang L ON ct.SITE_ID = L.LID\n\t\t\t\t\tinner join b_search_content sc on sc.ID = ct.SEARCH_CONTENT_ID\n\t\t\t\t\tINNER JOIN b_search_content_site scsite ON sc.ID = scsite.SEARCH_CONTENT_ID and ct.SITE_ID = scsite.SITE_ID\n\t\t\t\tWHERE\n\t\t\t\t\t" . CSearch::CheckPermissions("sc.ID") . "\n\t\t\t\t\tAND ct.SITE_ID = '" . SITE_ID . "'\n\t\t\t\t\tAND (" . implode(" OR ", $sqlWords) . ")\n\t\t\t\t\t" . (!empty($strSqlWhere) ? "AND " . $strSqlWhere : "") . "\n\t\t\t\tGROUP BY\n\t\t\t\t\tID, MODULE_ID, ITEM_ID, TITLE, PARAM1, PARAM2, DATE_CHANGE, DIR, SERVER_NAME, URL, SITE_URL, SITE_ID\n\t\t\t\t" . (count($sqlHaving) > 1 ? "HAVING " . implode(" AND ", $sqlHaving) : "") . "\n\t\t\t\tORDER BY " . ($bOrderByRank ? "RANK1 DESC, RANK2 DESC, RANK3 ASC, TITLE" : "DATE_CHANGE DESC, RANK1 DESC, RANK2 DESC, RANK3 ASC, TITLE") . "\n\t\t\t\tLIMIT 0, " . ($nTopCount + 1) . "\n\t\t\t"; $r = $DB->Query($strSql); parent::CDBResult($r); return true; } else { return false; } }
function ChangeIndex($MODULE_ID, $arFields, $ITEM_ID = false, $PARAM1 = false, $PARAM2 = false, $SITE_ID = false) { global $DB; if (is_set($arFields, "TITLE")) { $arFields["TITLE"] = Trim($arFields["TITLE"]); } if (is_set($arFields, "BODY")) { $arFields["BODY"] = Trim($arFields["BODY"]); } if (is_set($arFields) && is_array($arFields["PERMISSIONS"])) { CSearch::ChangePermission($MODULE_ID, $arFields["PERMISSIONS"], $ITEM_ID, $PARAM1, $PARAM2, $SITE_ID); } $strUpdate = $DB->PrepareUpdate("b_search_content", $arFields); if (strlen($strUpdate) > 0) { $strSqlWhere = CSearch::__PrepareFilter(array("MODULE_ID" => $MODULE_ID, "ITEM_ID" => $ITEM_ID, "PARAM1" => $PARAM1, "PARAM2" => $PARAM2, "SITE_ID" => $SITE_ID), $bIncSites); $strSql = "\n\t\t\t\tUPDATE b_search_content SET\n\t\t\t\t" . $strUpdate . "\n\t\t\t\tWHERE ID IN (\n\t\t\t\t\tSELECT sc.ID\n\t\t\t\t\tFROM b_search_content sc\n\t\t\t\t\t" . ($bIncSites ? "INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID" : "") . "\n\t\t\t\t\t" . (strlen($strSqlWhere) > 0 ? "WHERE " . $strSqlWhere : "") . "\n\t\t\t\t)\n\t\t\t"; $arBinds = array(); if (is_set($arFields, "BODY")) { $arBinds["BODY"] = $arFields["BODY"]; } if (is_set($arFields, "SEARCHABLE_CONTENT")) { $arBinds["SEARCHABLE_CONTENT"] = $arFields["SEARCHABLE_CONTENT"]; } $DB->QueryBind($strSql, $arBinds); } }
function ChangeIndex($MODULE_ID, $arFields, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $SITE_ID=false) { $DB = CDatabase::GetModuleConnection('search'); if(array_key_exists("TITLE", $arFields)) $arFields["TITLE"] = Trim($arFields["TITLE"]); if(array_key_exists("BODY", $arFields)) $arFields["BODY"] = Trim($arFields["BODY"]); if(array_key_exists("PERMISSIONS", $arFields) && is_array($arFields["PERMISSIONS"])) CSearch::ChangePermission($MODULE_ID, $arFields["PERMISSIONS"], $ITEM_ID, $PARAM1, $PARAM2, $SITE_ID); if(array_key_exists("SITE_ID", $arFields) && is_array($arFields["SITE_ID"])) CSearch::ChangeSite($MODULE_ID, $arFields["SITE_ID"], $ITEM_ID, $PARAM1, $PARAM2, $SITE_ID); $strUpdate = $DB->PrepareUpdate("b_search_content", $arFields); if(strlen($strUpdate) > 0) { $strSqlWhere = CSearch::__PrepareFilter(Array("MODULE_ID"=>$MODULE_ID, "ITEM_ID"=>$ITEM_ID, "PARAM1"=>$PARAM1, "PARAM2"=>$PARAM2, "SITE_ID"=>$SITE_ID), $bIncSites); $strSql = " SELECT sc.ID FROM b_search_content sc ".($bIncSites? "INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID": "")." ".(strlen($strSqlWhere)>0? "WHERE ".$strSqlWhere: "")." "; $rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); while($ar = $rs->Fetch()) { $strSql = "UPDATE b_search_content SET ".$strUpdate." WHERE ID=".$ar["ID"]; $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); if(array_key_exists("PARAMS", $arFields)) CSearch::SetContentItemParams($ar["ID"], $arFields["PARAMS"]); } } }
function ChangePermission($MODULE_ID, $arGroups, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $SITE_ID=false, $PARAMS=false) { $DB = CDatabase::GetModuleConnection('search'); $bIncSites = false; $strSqlWhere = CSearch::__PrepareFilter(array( "MODULE_ID"=>$MODULE_ID, "ITEM_ID"=>$ITEM_ID, "PARAM1"=>$PARAM1, "PARAM2"=>$PARAM2, "SITE_ID"=>$SITE_ID, "PARAMS"=>$PARAMS, ), $bIncSites); if($strSqlWhere) { $strSqlJoin1 = "INNER JOIN b_search_content sc ON sc.ID = b_search_content_right.SEARCH_CONTENT_ID"; $match = array(); //Copy first exists into inner join in hopeless try to defeat MySQL optimizer if(preg_match('#^\\s*EXISTS (\\(SELECT \\* FROM b_search_content_param WHERE SEARCH_CONTENT_ID = sc.ID AND PARAM_NAME = \'[^\']+\' AND PARAM_VALUE = \'[^\']+\'\\))#', $strSqlWhere, $match)) { $subTable = str_replace("SEARCH_CONTENT_ID = sc.ID AND", "", $match[1]); $strSqlJoin2 = "INNER JOIN ".$subTable." p1 ON p1.SEARCH_CONTENT_ID = sc.ID"; } else { $strSqlJoin2 = ""; } } else { $strSqlJoin1 = ""; $strSqlJoin2 = ""; } $rs = $DB->Query(" SELECT sc.ID FROM b_search_content sc ".$strSqlJoin2." ".($strSqlWhere? "WHERE ".$strSqlWhere: "" )." ", false, "File: ".__FILE__."<br>Line: ".__LINE__); while ($arR = $rs->fetch()) { CSearch::Update($arR["ID"], array("PERMISSIONS" => $arGroups)); } }
function Search($arParams, $aSort=array(), $aParamsEx=array(), $bTagsCloud = false) { $DB = CDatabase::GetModuleConnection('search'); if(!is_array($arParams)) $arParams = Array("QUERY"=>$arParams); if(!is_set($arParams, "SITE_ID") && is_set($arParams, "LID")) { $arParams["SITE_ID"] = $arParams["LID"]; unset($arParams["LID"]); } if(array_key_exists("TAGS", $arParams)) { $this->strTagsText = $arParams["TAGS"]; $arTags = explode(",", $arParams["TAGS"]); foreach($arTags as $i => $strTag) { $strTag = trim($strTag); if(strlen($strTag)) $arTags[$i] = str_replace("\"", "\\\"", $strTag); else unset($arTags[$i]); } if(count($arTags)) $arParams["TAGS"] = '"'.implode('","', $arTags).'"'; else unset($arParams["TAGS"]); } $this->strQueryText = $strQuery = trim($arParams["QUERY"]); $this->strTags = $strTags = $arParams["TAGS"]; if((strlen($strQuery) <= 0) && (strlen($strTags) > 0)) { $strQuery = $strTags; $bTagsSearch = true; } else { if(strlen($strTags)) $strQuery .= " ".$strTags; $strQuery = preg_replace ("'&#(\\d+);'e", "chr(\\1)", $strQuery); $bTagsSearch = false; } if(!array_key_exists("STEMMING", $aParamsEx)) $aParamsEx["STEMMING"] = COption::GetOptionString("search", "use_stemming", "N")=="Y"; $this->Query = new CSearchQuery("and", "yes", 0, $arParams["SITE_ID"]); if($this->_opt_NO_WORD_LOGIC) $this->Query->no_bool_lang = true; $query = $this->Query->GetQueryString((BX_SEARCH_VERSION > 1? "sct": "sc").".SEARCHABLE_CONTENT", $strQuery, $bTagsSearch, $aParamsEx["STEMMING"], $this->_opt_ERROR_ON_EMPTY_STEM); if(!$query || strlen(trim($query))<=0) { if($bTagsCloud) { $query = "1=1"; } else { $this->error = $this->Query->error; $this->errorno = $this->Query->errorno; return; } } if(strlen($query)>2000) { $this->error = GetMessage("SEARCH_ERROR4"); $this->errorno = 4; return; } foreach(GetModuleEvents("search", "OnSearch", true) as $arEvent) { $r = ""; if($bTagsSearch) { if(strlen($strTags)) $r = ExecuteModuleEventEx($arEvent, array("tags:".$strTags)); } else { $r = ExecuteModuleEventEx($arEvent, array($strQuery)); } if($r <> "") $this->url_add_params[] = $r; } if( BX_SEARCH_VERSION > 1 && count($this->Query->m_stemmed_words_id) && array_sum($this->Query->m_stemmed_words_id) === 0 ) { $r = new CDBResult; $r->InitFromArray(array()); } else { $bIncSites = false; $strSqlWhere = CSearch::__PrepareFilter($arParams, $bIncSites); if(strlen($strSqlWhere)>0) $strSqlWhere = " AND ".$strSqlWhere; if(is_array($aParamsEx) && count($aParamsEx)>0) { $arSqlWhere=array(); foreach($aParamsEx as $aParamEx) { $s=CSearch::__PrepareFilter($aParamEx, $bIncSites); if(strlen($s)>0) $arSqlWhere[]=$s; } if(count($arSqlWhere)>0) $strSqlWhere.="\n\t\t\t\tAND (\n\t\t\t\t\t(".implode(")\n\t\t\t\t\tOR(",$arSqlWhere).")\n\t\t\t\t)"; } //This will be used in suggest $this->strSqlWhere = $strSqlWhere; $strSqlOrder = $this->__PrepareSort($aSort, "sc.", $bTagsCloud); if(!array_key_exists("USE_TF_FILTER", $aParamsEx)) $aParamsEx["USE_TF_FILTER"] = COption::GetOptionString("search", "use_tf_cache") == "Y"; $bStem = !$bTagsSearch && count($this->Query->m_stemmed_words)>0; //calculate freq of the word on the whole site_id if($bStem && count($this->Query->m_stemmed_words)) { $arStat = $this->GetFreqStatistics($this->Query->m_lang, $this->Query->m_stemmed_words, $arParams["SITE_ID"]); $this->tf_hwm_site_id = (strlen($arParams["SITE_ID"]) > 0? $arParams["SITE_ID"]: ""); //we'll make filter by it's contrast if(!$bTagsCloud && $aParamsEx["USE_TF_FILTER"]) { $hwm = false; foreach($this->Query->m_stemmed_words as $i => $stem) { if(!array_key_exists($stem, $arStat)) { $hwm = 0; break; } elseif($hwm === false) { $hwm = $arStat[$stem]["TF"]; } elseif($hwm > $arStat[$stem]["TF"]) { $hwm = $arStat[$stem]["TF"]; } } if($hwm > 0) { $strSqlWhere .= " AND st.TF >= ".number_format($hwm, 2, ".", ""); $this->tf_hwm = $hwm; } } } if($bTagsCloud) $strSql = $this->tagsMakeSQL($query, $strSqlWhere, $strSqlOrder, $bIncSites, $bStem, $aParamsEx["LIMIT"]); else $strSql = $this->MakeSQL($query, $strSqlWhere, $strSqlOrder, $bIncSites, $bStem); //$tStart = getmicrotime(); $r = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); //echo "<pre>",htmlspecialcharsbx($strSql),"</pre><br>",(getmicrotime()-$tStart); } parent::CDBResult($r); }
public function Search($phrase = "", $nTopCount = 5, $arParams = array(), $bNotFilter = false, $order = "") { $DB = CDatabase::GetModuleConnection('search'); $this->_arPhrase = stemming_split($phrase, LANGUAGE_ID); $bOrderByRank = ($order == "rank"); if(!empty($this->_arPhrase)) { $nTopCount = intval($nTopCount); if($nTopCount <= 0) $nTopCount = 5; $sqlHaving = array(); $sqlWords = array(); foreach(array_reverse($this->_arPhrase, true) as $word => $pos) { if(empty($sqlWords) && !preg_match("/[\\n\\r \\t]$/", $phrase)) $s = $sqlWords[] = "ct.WORD like '".$DB->ForSQL($word)."%'"; else $s = $sqlWords[] = "ct.WORD = '".$DB->ForSQL($word)."'"; $sqlHaving[] = "(sum(".$s.") > 0)"; } $bIncSites = false; $strSqlWhere = CSearch::__PrepareFilter($arParams, $bIncSites); if($bNotFilter) { if(!empty($strSqlWhere)) $strSqlWhere = "NOT (".$strSqlWhere.")"; else $strSqlWhere = "1=0"; } $strSql = " SELECT sc.ID ,sc.MODULE_ID ,sc.ITEM_ID ,sc.TITLE ,sc.PARAM1 ,sc.PARAM2 ,sc.DATE_CHANGE ,L.DIR ,L.SERVER_NAME ,sc.URL as URL ,scsite.URL as SITE_URL ,scsite.SITE_ID ,if(locate('".$DB->ForSQL(ToUpper($phrase))."', upper(sc.TITLE)) > 0, 1, 0) RANK1 ,count(1) RANK2 ,min(ct.POS) RANK3 FROM b_search_content_title ct INNER JOIN b_lang L ON ct.SITE_ID = L.LID inner join b_search_content sc on sc.ID = ct.SEARCH_CONTENT_ID INNER JOIN b_search_content_site scsite ON sc.ID = scsite.SEARCH_CONTENT_ID and ct.SITE_ID = scsite.SITE_ID WHERE ".CSearch::CheckPermissions("sc.ID")." AND ct.SITE_ID = '".SITE_ID."' AND (".implode(" OR ", $sqlWords).") ".(!empty($strSqlWhere)? "AND ".$strSqlWhere: "")." GROUP BY ID, MODULE_ID, ITEM_ID, TITLE, PARAM1, PARAM2, DATE_CHANGE, DIR, SERVER_NAME, URL, SITE_URL, SITE_ID ".(count($sqlHaving) > 1? "HAVING ".implode(" AND ", $sqlHaving): "")." ORDER BY ".( $bOrderByRank? "RANK1 DESC, RANK2 DESC, RANK3 ASC, TITLE": "DATE_CHANGE DESC, RANK1 DESC, RANK2 DESC, RANK3 ASC, TITLE" )." LIMIT 0, ".($nTopCount+1)." "; $r = $DB->Query($strSql); parent::CDBResult($r); return true; } else { return false; } }