Beispiel #1
0
 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;
     }
 }
Beispiel #2
0
 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);
     }
 }
Beispiel #3
0
	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"]);
			}
		}
	}
Beispiel #4
0
	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));
		}
	}
Beispiel #5
0
	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);
	}
Beispiel #6
0
	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;
		}
	}