Current Path : /var/www/html/clients/old.e-nkama.ru/e-nkama_bitrix/bitrix/modules/search/classes/mysql/ |
Current File : /var/www/html/clients/old.e-nkama.ru/e-nkama_bitrix/bitrix/modules/search/classes/mysql/search.php |
<? require_once($_SERVER["DOCUMENT_ROOT"]."/bitrix/modules/search/classes/general/search.php"); class CSearch extends CAllSearch { function MakeSQL($query, $strSqlWhere, $strSort, $bIncSites, $bStem) { global $DB, $USER; if(strpos($strSort, "TITLE_RANK") !== false) { if($bStem) { $strSelect = ""; foreach($this->Query->m_stemmed_words as $stem) { if(strlen($strSelect) > 0) $strSelect .= " + "; $strSelect .= "if(locate('".$stem."', upper(sc.TITLE)) > 0, 1, 0)"; } $strSelect = ",".$strSelect." TITLE_RANK\n"; } else { $strSelect = ""; foreach($this->Query->m_words as $word) { if(strlen($strSelect) > 0) $strSelect .= " + "; $strSelect .= "if(locate('".$DB->ForSql(ToUpper($word))."', upper(sc.TITLE)) > 0, 1, 0)"; } $strSelect = ",".$strSelect." TITLE_RANK\n"; } } else { $strSelect = ""; } if($bIncSites && $bStem) { if(strpos($query, "sc.")===false) { $strSqlWhere = preg_replace('# AND st.TF >= [0-9\.,]+#i', "", $strSqlWhere); $strSql = " SELECT sc.ID ,sc.MODULE_ID ,sc.ITEM_ID ,sc.LID ,sc.TITLE ,sc.TAGS ,sc.BODY ,sc.SEARCHABLE_CONTENT ,sc.PARAM1 ,sc.PARAM2 ,sc.UPD ,sc.DATE_FROM ,sc.DATE_TO ,L.DIR ,L.SERVER_NAME ,sc.URL as URL ,stt.TF as RANK ,scsite.URL as SITE_URL ,scsite.SITE_ID ,".$DB->DateToCharFunction("sc.DATE_CHANGE")." as FULL_DATE_CHANGE ,".$DB->DateToCharFunction("sc.DATE_CHANGE", "SHORT")." as DATE_CHANGE ".$strSelect." FROM b_search_content sc INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID INNER JOIN b_lang L ON scsite.SITE_ID=L.LID INNER JOIN ".(count($this->Query->m_stemmed_words) > 1? "( select search_content_id, max(st.TF) TF, sum(st.TF/sf.FREQ) as RANK from b_search_content_stem st, b_search_content_freq sf where st.language_id = '".$this->Query->m_lang."' and st.stem = sf.stem and sf.language_id = st.language_id and st.stem in ('".implode("' ,'", $this->Query->m_stemmed_words)."') ".($this->tf_hwm > 0? "and st.TF >= ".number_format($this->tf_hwm, 2, ".", ""): "")." ".(strlen($this->tf_hwm_site_id) > 0? "and sf.SITE_ID = '".$DB->ForSQL($this->tf_hwm_site_id, 2)."'": "and sf.SITE_ID IS NULL")." group by st.search_content_id having (".$query.") )" : "( select st0.search_content_id, st0.TF, st0.TF RANK from b_search_content_stem st0 where st0.language_id = '".$this->Query->m_lang."' and st0.stem in ('".implode("' ,'", $this->Query->m_stemmed_words)."') ".($this->tf_hwm > 0? "and st0.TF >= ".number_format($this->tf_hwm, 2, ".", ""): "")." )" )." stt ON sc.id = stt.search_content_id WHERE ".CSearch::CheckPermissions("sc.ID")." ".$strSqlWhere." ".$strSort." "; } else { $strSql = " SELECT sc.ID ,sc.MODULE_ID ,sc.ITEM_ID ,sc.LID ,sc.TITLE ,sc.TAGS ,sc.BODY ,sc.SEARCHABLE_CONTENT ,sc.PARAM1 ,sc.PARAM2 ,sc.UPD ,sc.DATE_FROM ,sc.DATE_TO ,L.DIR ,L.SERVER_NAME ,sc.URL as URL ,".(count($this->Query->m_stemmed_words)>1?"sum(st.TF/sf.FREQ)":"st.TF")." as RANK ,scsite.URL as SITE_URL ,scsite.SITE_ID ,".$DB->DateToCharFunction("sc.DATE_CHANGE")." as FULL_DATE_CHANGE ,".$DB->DateToCharFunction("sc.DATE_CHANGE", "SHORT")." as DATE_CHANGE ".$strSelect." FROM b_search_content sc INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID INNER JOIN b_lang L ON scsite.SITE_ID=L.LID INNER JOIN b_search_content_stem st ON sc.id = st.search_content_id+0 ".(count($this->Query->m_stemmed_words)>1? "INNER JOIN b_search_content_freq sf ON st.language_id = sf.language_id and st.stem=sf.stem ".(strlen($this->tf_hwm_site_id) > 0? "and sf.SITE_ID = '".$DB->ForSQL($this->tf_hwm_site_id, 2)."'": "and sf.SITE_ID IS NULL" ): "" )." WHERE ".CSearch::CheckPermissions("sc.ID")." AND st.STEM in ('".implode("','", $this->Query->m_stemmed_words)."') ".(count($this->Query->m_stemmed_words)>1? "AND sf.STEM in ('".implode("','", $this->Query->m_stemmed_words)."')": "")." AND st.language_id='".$this->Query->m_lang."' ".$strSqlWhere." GROUP BY sc.ID ,L.DIR ,L.SERVER_NAME ,scsite.URL ,scsite.SITE_ID HAVING (".$query.") ".$strSort." "; } } elseif($bIncSites && !$bStem) $strSql = " SELECT DISTINCT sc.ID ,sc.MODULE_ID ,sc.ITEM_ID ,sc.LID ,sc.TITLE ,sc.TAGS ,sc.BODY ,sc.SEARCHABLE_CONTENT ,sc.PARAM1 ,sc.PARAM2 ,sc.UPD ,sc.DATE_FROM ,sc.DATE_TO ,L.DIR ,L.SERVER_NAME ,sc.URL as URL ,1 as RANK ,scsite.URL as SITE_URL ,scsite.SITE_ID ,".$DB->DateToCharFunction("sc.DATE_CHANGE")." as FULL_DATE_CHANGE ,".$DB->DateToCharFunction("sc.DATE_CHANGE", "SHORT")." as DATE_CHANGE ".$strSelect." FROM b_search_content sc INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID INNER JOIN b_lang L ON scsite.SITE_ID=L.LID ".($this->Query->bTagsSearch? " INNER JOIN b_search_tags stags ON (sc.ID = stags.SEARCH_CONTENT_ID) WHERE ".CSearch::CheckPermissions("sc.ID")." ".$strSqlWhere." ".(is_array($this->Query->m_tags_words) && count($this->Query->m_tags_words)>0? "AND stags.NAME in ('".implode("','", $this->Query->m_tags_words)."')": "")." GROUP BY sc.ID ,L.DIR ,L.SERVER_NAME ,scsite.URL ,scsite.SITE_ID HAVING (".$query.")": " WHERE ".CSearch::CheckPermissions("sc.ID")." AND (".$query.") ".$strSqlWhere."")." ".$strSort." "; elseif(!$bIncSites && $bStem) $strSql = " SELECT sc.ID ,sc.MODULE_ID ,sc.ITEM_ID ,sc.LID ,sc.TITLE ,sc.TAGS ,sc.BODY ,sc.SEARCHABLE_CONTENT ,sc.PARAM1 ,sc.PARAM2 ,sc.UPD ,sc.DATE_FROM ,sc.DATE_TO ,L.DIR ,L.SERVER_NAME ,sc.URL as URL ".(count($this->Query->m_stemmed_words)>1?",sum(st.TF/sf.FREQ)":",st.TF")." as RANK ,".$DB->DateToCharFunction("sc.DATE_CHANGE")." as FULL_DATE_CHANGE ,".$DB->DateToCharFunction("sc.DATE_CHANGE", "SHORT")." as DATE_CHANGE ".$strSelect." FROM b_search_content sc INNER JOIN b_lang L ON sc.LID=L.LID INNER JOIN b_search_content_stem st ON sc.id = st.search_content_id ".(count($this->Query->m_stemmed_words)>1? "INNER JOIN b_search_content_freq sf ON st.language_id = sf.language_id and st.stem=sf.stem ".(strlen($this->tf_hwm_site_id) > 0? "and sf.SITE_ID = '".$DB->ForSQL($this->tf_hwm_site_id, 2)."'": "and sf.SITE_ID IS NULL" ): "" )." WHERE ".CSearch::CheckPermissions("sc.ID")." AND st.STEM in ('".implode("','", $this->Query->m_stemmed_words)."') ".(count($this->Query->m_stemmed_words)>1? "AND sf.STEM in ('".implode("','", $this->Query->m_stemmed_words)."')": "")." AND st.language_id='".$this->Query->m_lang."' ".$strSqlWhere." ".(count($this->Query->m_stemmed_words)>1?" GROUP BY sc.ID ,L.DIR ,L.SERVER_NAME HAVING (".$query.") ": "")." ".$strSort." "; else //if(!$bIncSites && !$bStem) $strSql = " SELECT DISTINCT sc.ID ,sc.MODULE_ID ,sc.ITEM_ID ,sc.LID ,sc.TITLE ,sc.TAGS ,sc.BODY ,sc.SEARCHABLE_CONTENT ,sc.PARAM1 ,sc.PARAM2 ,sc.UPD ,sc.DATE_FROM ,sc.DATE_TO ,L.DIR ,L.SERVER_NAME ,sc.URL as URL ,1 as RANK ,".$DB->DateToCharFunction("sc.DATE_CHANGE")." as FULL_DATE_CHANGE ,".$DB->DateToCharFunction("sc.DATE_CHANGE", "SHORT")." as DATE_CHANGE ".$strSelect." FROM b_search_content sc INNER JOIN b_lang L ON sc.LID=L.LID ".($this->Query->bTagsSearch? "INNER JOIN b_search_tags stags ON (sc.ID = stags.SEARCH_CONTENT_ID) WHERE ".CSearch::CheckPermissions("sc.ID")." ".$strSqlWhere." ".(is_array($this->Query->m_tags_words) && count($this->Query->m_tags_words)>0? "AND stags.NAME in ('".implode("','", $this->Query->m_tags_words)."')": "")." GROUP BY sc.ID ,L.DIR ,L.SERVER_NAME HAVING (".$query.")" : " WHERE (".$query.") ".$strSqlWhere." ")." ".$strSort." "; $limit = COption::GetOptionInt("search", "max_result_size"); if($limit<1) $limit=500; return $strSql."LIMIT ".$limit; } function CheckPermissions($FIELD = "sc.ID") { global $USER; $arResult = array(); if($USER->IsAdmin()) { $arResult[] = "1=1"; } else { $arResult[] = " EXISTS ( SELECT 1 FROM b_search_content_group scg WHERE ".$FIELD." = scg.SEARCH_CONTENT_ID AND scg.GROUP_ID IN (".implode(",", $USER->GetUserGroupArray()).") )"; $events = GetModuleEvents("search", "OnSearchCheckPermissions"); while($arEvent = $events->Fetch()) { $strCheck = ExecuteModuleEventEx($arEvent, array($FIELD)); if(strlen($strCheck)) $arResult[] = $strCheck; } } return "((".implode(") OR (", $arResult)."))"; } function tagsMakeSQL($query, $strSqlWhere, $strSort, $bIncSites, $bStem, $limit = 100) { global $DB, $USER; $limit = intVal($limit); if($bStem && count($this->Query->m_stemmed_words)>1) {//We have to make some magic in case quotes was used in query //We have to move (sc.searchable_content LIKE '%".ToUpper($word)."%') from $query to $strSqlWhere while(preg_match("/(AND\s+\(sc.searchable_content LIKE \'\%.+?\%\'\))/", $query, $arMatches)) { $strSqlWhere .= $arMatches[0]; $query = str_replace($arMatches[0], "", $query); } } if($bIncSites && $bStem) $strSql = " SELECT stags.NAME ,COUNT(DISTINCT stags.SEARCH_CONTENT_ID) as CNT ,MAX(sc.DATE_CHANGE) DC_TMP ,".$DB->DateToCharFunction("MAX(sc.DATE_CHANGE)")." as FULL_DATE_CHANGE ,".$DB->DateToCharFunction("MAX(sc.DATE_CHANGE)", "SHORT")." as DATE_CHANGE ".(count($this->Query->m_stemmed_words)>1 && strpos($query, "searchable_content")!==false?" ,sc.SEARCHABLE_CONTENT ": "")." FROM b_search_tags stags INNER JOIN b_search_content sc ON (stags.SEARCH_CONTENT_ID=sc.ID) INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID INNER JOIN b_search_content_stem st ON sc.id = st.search_content_id ".(count($this->Query->m_stemmed_words)>1? "INNER JOIN b_search_content_freq sf ON st.language_id = sf.language_id and st.stem=sf.stem ".(strlen($this->tf_hwm_site_id) > 0? "and sf.SITE_ID = '".$DB->ForSQL($this->tf_hwm_site_id, 2)."'": "and sf.SITE_ID IS NULL" ): "" )." WHERE ".CSearch::CheckPermissions("sc.ID")." AND st.STEM in ('".implode("','", $this->Query->m_stemmed_words)."') ".(count($this->Query->m_stemmed_words)>1? "AND sf.STEM in ('".implode("','", $this->Query->m_stemmed_words)."')": "")." AND st.language_id='".$this->Query->m_lang."' AND stags.SITE_ID = scsite.SITE_ID ".$strSqlWhere." GROUP BY stags.NAME ".((count($this->Query->m_stemmed_words)>1)?" HAVING (".$query.") ": "")." ".$strSort." "; elseif($bIncSites && !$bStem) { if($query == "1=1") { $strSql = " SELECT stags2.NAME ,COUNT(DISTINCT stags2.SEARCH_CONTENT_ID) as CNT ,MAX(sc.DATE_CHANGE) DC_TMP ,".$DB->DateToCharFunction("MAX(sc.DATE_CHANGE)")." as FULL_DATE_CHANGE ,".$DB->DateToCharFunction("MAX(sc.DATE_CHANGE)", "SHORT")." as DATE_CHANGE FROM b_search_tags stags2 INNER JOIN b_search_content sc ON (stags2.SEARCH_CONTENT_ID=sc.ID) INNER JOIN b_search_content_site scsite ON (sc.ID=scsite.SEARCH_CONTENT_ID AND stags2.SITE_ID=scsite.SITE_ID) WHERE ".CSearch::CheckPermissions("sc.ID")." AND ".($this->Query->bTagsSearch? ( //Index range scan optimization (make it for other queries ???) is_array($this->Query->m_tags_words) && count($this->Query->m_tags_words)? "stags.name in ('".implode("', '", $this->Query->m_tags_words)."')": "(1=1)" ) : "(".$query.")")." ".$strSqlWhere." GROUP BY stags2.NAME ".$strSort." "; } else { $strSql = " SELECT stags2.NAME ,COUNT(DISTINCT stags.SEARCH_CONTENT_ID) as CNT ,MAX(sc.DATE_CHANGE) DC_TMP ,".$DB->DateToCharFunction("MAX(sc.DATE_CHANGE)")." as FULL_DATE_CHANGE ,".$DB->DateToCharFunction("MAX(sc.DATE_CHANGE)", "SHORT")." as DATE_CHANGE FROM b_search_tags stags2 INNER JOIN b_search_tags stags ON (stags.SEARCH_CONTENT_ID=stags2.SEARCH_CONTENT_ID and stags.SITE_ID=stags2.SITE_ID) INNER JOIN b_search_content sc ON (stags.SEARCH_CONTENT_ID=sc.ID) INNER JOIN b_search_content_site scsite ON (sc.ID=scsite.SEARCH_CONTENT_ID AND stags.SITE_ID=scsite.SITE_ID) WHERE ".CSearch::CheckPermissions("sc.ID")." AND ".($this->Query->bTagsSearch? ( //Index range scan optimization (make it for other queries ???) is_array($this->Query->m_tags_words) && count($this->Query->m_tags_words)? "stags.name in ('".implode("', '", $this->Query->m_tags_words)."')": "(1=1)" ) : "(".$query.")")." ".$strSqlWhere." GROUP BY stags2.NAME ".($this->Query->bTagsSearch? " HAVING (".$query.")": "")." ".$strSort." "; } } elseif(!$bIncSites && $bStem) $strSql = " SELECT stags.NAME ,COUNT(DISTINCT stags.SEARCH_CONTENT_ID) as CNT ,MAX(sc.DATE_CHANGE) DC_TMP , ".$DB->DateToCharFunction("MAX(sc.DATE_CHANGE)")." as FULL_DATE_CHANGE , ".$DB->DateToCharFunction("MAX(sc.DATE_CHANGE)", "SHORT")." as DATE_CHANGE ".(count($this->Query->m_stemmed_words)>1 && strpos($query, "searchable_content")!==false?" ,sc.SEARCHABLE_CONTENT ": "")." FROM b_search_tags stags INNER JOIN b_search_content sc ON (stags.SEARCH_CONTENT_ID=sc.ID) INNER JOIN b_search_content_stem st ON sc.id = st.search_content_id ".(count($this->Query->m_stemmed_words)>1? "INNER JOIN b_search_content_freq sf ON st.language_id = sf.language_id and st.stem=sf.stem ".(strlen($this->tf_hwm_site_id) > 0? "and sf.SITE_ID = '".$DB->ForSQL($this->tf_hwm_site_id, 2)."'": "and sf.SITE_ID IS NULL" ): "" )." WHERE ".CSearch::CheckPermissions("sc.ID")." AND st.STEM in ('".implode("','", $this->Query->m_stemmed_words)."') ".(count($this->Query->m_stemmed_words)>1? "AND sf.STEM in ('".implode("','", $this->Query->m_stemmed_words)."')": "")." AND st.language_id='".$this->Query->m_lang."' ".$strSqlWhere." GROUP BY stags.NAME ".(count($this->Query->m_stemmed_words)>1?" ,sc.ID ,sc.SEARCHABLE_CONTENT HAVING (".$query.") ": "")." ".$strSort." "; else //if(!$bIncSites && !$bStem) $strSql = " SELECT stags2.NAME ,COUNT(DISTINCT stags.SEARCH_CONTENT_ID) as CNT ,MAX(sc.DATE_CHANGE) DC_TMP ,".$DB->DateToCharFunction("MAX(sc.DATE_CHANGE)")." as FULL_DATE_CHANGE ,".$DB->DateToCharFunction("MAX(sc.DATE_CHANGE)", "SHORT")." as DATE_CHANGE FROM b_search_tags stags2 INNER JOIN b_search_tags stags ON (stags.SEARCH_CONTENT_ID=stags2.SEARCH_CONTENT_ID and stags.SITE_ID=stags2.SITE_ID) INNER JOIN b_search_content sc ON (stags.SEARCH_CONTENT_ID=sc.ID) WHERE ".CSearch::CheckPermissions("sc.ID")." AND ".($this->Query->bTagsSearch? ( //Index range scan optimization (make it for other queries ???) is_array($this->Query->m_tags_words) && count($this->Query->m_tags_words)? "stags.name in ('".implode("', '", $this->Query->m_tags_words)."')": "(1=1)" ) : "(".$query.")")." ".$strSqlWhere." GROUP BY stags2.NAME ".($this->Query->bTagsSearch? " HAVING (".$query.")": "")." ".$strSort." "; if($limit < 1) $limit = 150; return $strSql."LIMIT ".$limit; } function ReindexLock() { //do not lock for mysql database } function DeleteOld($SESS_ID, $MODULE_ID="", $SITE_ID="") { global $DB; $strFilter = ""; if($MODULE_ID!="") $strFilter.=" AND MODULE_ID = '".$DB->ForSql($MODULE_ID)."' "; $strJoin = ""; if($SITE_ID!="") { $strFilter.=" AND scsite.SITE_ID = '".$DB->ForSql($SITE_ID)."' "; $strJoin.=" INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID "; } if(!is_array($SESS_ID)) $SESS_ID = array($SESS_ID); $strSql = " SELECT ID FROM b_search_content sc ".$strJoin." WHERE (UPD not in ('".implode("', '", $SESS_ID)."') OR UPD IS NULL) ".$strFilter." "; $arEvents = array(); $db_events = GetModuleEvents("search", "OnBeforeIndexDelete"); while($arEvent = $db_events->Fetch()) $arEvents[] = $arEvent; $rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); while($ar = $rs->Fetch()) { foreach($arEvents as $arEvent) ExecuteModuleEventEx($arEvent, array("SEARCH_CONTENT_ID = ".$ar["ID"])); $DB->Query("DELETE FROM b_search_content_group WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content_stem WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content WHERE ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); } CSearchTags::CleanCache(); } function DeleteForReindex($MODULE_ID) { global $DB; $MODULE_ID = $DB->ForSql($MODULE_ID); $strSql = "SELECT ID FROM b_search_content WHERE MODULE_ID = '".$MODULE_ID."'"; $arEvents = array(); $db_events = GetModuleEvents("search", "OnBeforeIndexDelete"); while($arEvent = $db_events->Fetch()) $arEvents[] = $arEvent; $rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); while($ar = $rs->Fetch()) { foreach($arEvents as $arEvent) ExecuteModuleEventEx($arEvent, array("SEARCH_CONTENT_ID = ".$ar["ID"])); $DB->Query("DELETE FROM b_search_content_group WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content_stem WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content WHERE ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); } CSearchTags::CleanCache(); } function OnLangDelete($lang) { global $DB; $lang = $DB->ForSql($lang); $strSql = " SELECT SEARCH_CONTENT_ID ID FROM b_search_content_site WHERE SITE_ID='".$lang."' GROUP BY SEARCH_CONTENT_ID HAVING COUNT(*)=1 "; $arEvents = array(); $db_events = GetModuleEvents("search", "OnBeforeIndexDelete"); while($arEvent = $db_events->Fetch()) $arEvents[] = $arEvent; $rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); while($ar = $rs->Fetch()) { foreach($arEvents as $arEvent) ExecuteModuleEventEx($arEvent, array("SEARCH_CONTENT_ID = ".$ar["ID"])); $DB->Query("DELETE FROM b_search_content_group WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content_stem WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content WHERE ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); } $DB->Query("DELETE FROM b_search_content_site WHERE SITE_ID='".$lang."'", false, "File: ".__FILE__."<br>Line: ".__LINE__); $r = $DB->Query(" SELECT sc.ID, MIN(scsite.SITE_ID) as SITE_ID FROM b_search_content sc, b_search_content_site scsite WHERE sc.LID = '".$lang."' AND sc.ID = scsite.SEARCH_CONTENT_ID AND scsite.SITE_ID <> '".$lang."' GROUP BY sc.ID ", false, "File: ".__FILE__."<br>Line: ".__LINE__); while($arR = $r->Fetch()) $DB->Query("UPDATE b_search_content SET LID = '".$arR["SITE_ID"]."' WHERE ID=".$arR["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content WHERE LID='".$lang."'", false, "File: ".__FILE__."<br>Line: ".__LINE__); CSearchTags::CleanCache(); } function ChangePermission($MODULE_ID, $arGroups, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $SITE_ID=false) { global $DB; $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": "")." WHERE ".$strSqlWhere." "; $rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); while($ar = $rs->Fetch()) $DB->Query("DELETE FROM b_search_content_group WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $arNewGroups = array(); foreach($arGroups as $group) { $group = intval($group); if($group > 0) $arNewGroups[$group] = $group; } if(count($arNewGroups)) { if(strlen($strSqlWhere)>0) $strSqlWhere = "AND ".$strSqlWhere; $strSql = " INSERT INTO b_search_content_group(SEARCH_CONTENT_ID, GROUP_ID) SELECT DISTINCT sc.ID, g.ID FROM b_group g, b_search_content sc ".($bIncSites?" INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID ":"")." WHERE g.ID IN (".implode(",", $arNewGroups).") ".$strSqlWhere." "; $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); } } function ChangeSite($MODULE_ID, $arSite, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $SITE_ID=false) { global $DB; $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": "")." WHERE ".$strSqlWhere." "; $r = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); while($arR = $r->Fetch()) { $DB->Query("DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ".$arR["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $bFirst = true; foreach($arSite as $site => $url) { if($bFirst) { $strSql = " UPDATE b_search_content SET LID = '".$DB->ForSql($site, 2)."', URL = '".$DB->ForSql($url, 2000)."' WHERE ID = ".$arR["ID"]." "; $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); $bFirst = false; } $strSql = " INSERT INTO b_search_content_site(SEARCH_CONTENT_ID, SITE_ID, URL) VALUES(".$arR["ID"].", '".$DB->ForSql($site, 2)."', '".$DB->ForSql($url, 2000)."')"; $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); } } } function DeleteIndex($MODULE_ID, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $SITE_ID=false) { global $DB; if($PARAM1 !== false && $PARAM2 !== false) $strSqlWhere = CSearch::__PrepareFilter(Array("MODULE_ID"=>$MODULE_ID, "ITEM_ID"=>$ITEM_ID, array("=PARAM1"=>$PARAM1, "PARAM2"=>$PARAM2), "SITE_ID"=>$SITE_ID), $bIncSites); else $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" :"")." WHERE ".$strSqlWhere." "; $arEvents = array(); $db_events = GetModuleEvents("search", "OnBeforeIndexDelete"); while($arEvent = $db_events->Fetch()) $arEvents[] = $arEvent; $rs = $DB->Query($strSql, false, "File: ".__FILE__."<br>Line: ".__LINE__); while($ar = $rs->Fetch()) { foreach($arEvents as $arEvent) ExecuteModuleEventEx($arEvent, array("SEARCH_CONTENT_ID = ".$ar["ID"])); $DB->Query("DELETE FROM b_search_content_group WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content_stem WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); $DB->Query("DELETE FROM b_search_content WHERE ID = ".$ar["ID"], false, "File: ".__FILE__."<br>Line: ".__LINE__); } CSearchTags::CleanCache(); } function FormatDateString($strField) { return "DATE_FORMAT(".$strField.", '%d.%m.%Y %H:%i:%s')"; } function FormatLimit($strSql, $limit) { return str_replace("/*TOP*/", "", $strSql)."LIMIT ".intval($limit); } function Update($ID, $arFields) { global $DB; if(is_set($arFields, "LAST_MODIFIED")) $arFields["DATE_CHANGE"] = $arFields["LAST_MODIFIED"]; elseif(is_set($arFields, "DATE_CHANGE")) $arFields["DATE_CHANGE"] = $DB->FormatDate($arFields["DATE_CHANGE"], "DD.MM.YYYY HH.MI.SS", CLang::GetDateFormat()); $strUpdate = $DB->PrepareUpdate("b_search_content", $arFields); if(strlen($strUpdate) > 0) { $DB->Query("UPDATE b_search_content SET ".$strUpdate." WHERE ID=".intval($ID), false, "File: ".__FILE__."<br>Line: ".__LINE__); } } function CleanFreqCache($ID) { global $DB; $rs = $DB->Query("SELECT LANGUAGE_ID,STEM FROM b_search_content_stem WHERE SEARCH_CONTENT_ID = ".intval($ID), false, "File: ".__FILE__."<br>Line: ".__LINE__); while($ar = $rs->Fetch()) { $DB->Query(" UPDATE b_search_content_freq SET TF = null WHERE TF is not null AND LANGUAGE_ID = '".$DB->ForSQL($ar["LANGUAGE_ID"])."' AND STEM = '".$DB->ForSQL($ar["STEM"])."' ", false, "File: ".__FILE__."<br>Line: ".__LINE__); } } function StemIndex($arLID, $ID, $sContent) { global $DB; static $CACHE_SITE_LANGS = array(); $arLang=array(); if(!is_array($arLID)) $arLID = Array(); foreach($arLID as $site=>$url) { if(!array_key_exists($site, $CACHE_SITE_LANGS)) { $db_site_tmp = CSite::GetByID($site); if ($ar_site_tmp = $db_site_tmp->Fetch()) $CACHE_SITE_LANGS[$site] = array( "LANGUAGE_ID" => $ar_site_tmp["LANGUAGE_ID"], "CHARSET" => $ar_site_tmp["CHARSET"], "SERVER_NAME" => $ar_site_tmp["SERVER_NAME"] ); else $CACHE_SITE_LANGS[$site] = false; } if(is_array($CACHE_SITE_LANGS[$site])) $arLang[$CACHE_SITE_LANGS[$site]["LANGUAGE_ID"]]++; } foreach($arLang as $lang=>$value) { $arDoc = stemming($sContent, $lang); $docLength = array_sum($arDoc); if($docLength > 0) { $doc = ""; $logDocLength = log($docLength<20?20:$docLength); $strSqlPrefix = " insert into b_search_content_stem (SEARCH_CONTENT_ID, LANGUAGE_ID, STEM, TF) values "; $maxValuesLen = 2048; $strSqlValues = ""; foreach($arDoc as $word => $count) { $strSqlValues .= ",\n(".$ID.", '".$lang."', '".$DB->ForSql($word)."', ". number_format(log($count+1)/$logDocLength, 4, ".", "").")"; if(strlen($strSqlValues) > $maxValuesLen) { $DB->Query($strSqlPrefix.substr($strSqlValues, 2), false, "File: ".__FILE__."<br>Line: ".__LINE__); $strSqlValues = ""; } } if(strlen($strSqlValues) > 0) { $DB->Query($strSqlPrefix.substr($strSqlValues, 2), false, "File: ".__FILE__."<br>Line: ".__LINE__); $strSqlValues = ""; } } } } function TagsIndex($arLID, $ID, $sContent) { global $DB; if(!is_array($arLID)) $arLID = Array(); $sContent = str_replace("\x00", "", $sContent); foreach($arLID as $site_id => $url) { $arTags = tags_prepare($sContent, $site_id); if(!empty($arTags)) { $strSqlPrefix = " insert into b_search_tags (SEARCH_CONTENT_ID, SITE_ID, NAME) values "; $maxValuesLen = 2048; $strSqlValues = ""; CSearchTags::CleanCache($arTags); foreach($arTags as $tag) { $strSqlValues .= ",\n(".$ID.", '".$site_id."', '".$DB->ForSql($tag, 255)."')"; if(strlen($strSqlValues) > $maxValuesLen) { $DB->Query($strSqlPrefix.substr($strSqlValues, 2), false, "File: ".__FILE__."<br>Line: ".__LINE__); $strSqlValues = ""; } } if(strlen($strSqlValues) > 0) { $DB->Query($strSqlPrefix.substr($strSqlValues, 2), false, "File: ".__FILE__."<br>Line: ".__LINE__); $strSqlValues = ""; } } } } function ChangeIndex($MODULE_ID, $arFields, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $SITE_ID=false) { global $DB; 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__); } } } } class CSearchQuery extends CAllSearchQuery { var $cnt = 0; function BuildWhereClause($word) { global $DB; $this->cnt++; if($this->cnt>10) return "1=1"; if(isset($this->m_kav[$word])) { $word = $this->m_kav[$word]; $bInQuotes = true; } else { $bInQuotes = false; } $this->m_words[] = $word; $word = $DB->ForSql($word, 100); if($this->bTagsSearch) { if(strpos($word, "%")===false) { //We can optimize query by doing range scan if(is_array($this->m_tags_words)) $this->m_tags_words[] = $word; $op = "="; } else { //Optimization is not possible $this->m_tags_words = false; $op = "like"; } return "(sum(stags.name ".$op." '".$word."')>0)"; } elseif($this->bStemming && !$bInQuotes) { $word = ToUpper($word); $this->m_stemmed_words[] = $word; return "(sum(st.stem = '".$word."')>0)"; } else { return "(sc.searchable_content LIKE '%".str_replace(array("%", "_"), array("\\%", "\\_") ,ToUpper($word))."%')"; } } } ?>