4if (!defined(
'START_EXEC_TIME'))
6 define(
'START_EXEC_TIME', microtime(
true));
32 function __construct($strQuery =
false,
$SITE_ID =
false, $MODULE_ID =
false, $ITEM_ID =
false, $PARAM1 =
false, $PARAM2 =
false, $aSort = [], $aParamsEx = [], $bTagsCloud =
false)
34 $this->limit = (int)COption::GetOptionInt(
'search',
'max_result_size');
40 $this->
CSearch($strQuery,
$SITE_ID, $MODULE_ID, $ITEM_ID, $PARAM1, $PARAM2, $aSort, $aParamsEx, $bTagsCloud);
43 function CSearch($strQuery =
false, $LID =
false, $MODULE_ID =
false, $ITEM_ID =
false, $PARAM1 =
false, $PARAM2 =
false, $aSort = [], $aParamsEx = [], $bTagsCloud =
false)
45 if ($strQuery ===
false)
57 $this->
Search($arParams, $aSort, $aParamsEx, $bTagsCloud);
64 $DB = CDatabase::GetModuleConnection(
'search');
80 $arTags = explode(
',',
$arParams[
'TAGS']);
81 foreach ($arTags as
$i => $strTag)
83 $strTag = trim($strTag);
86 $arTags[
$i] = str_replace(
'"',
'\\"', $strTag);
96 $arParams[
'TAGS'] =
'"' . implode(
'","', $arTags) .
'"';
104 $this->strQueryText = $strQuery = trim(
$arParams[
'QUERY']);
118 $strQuery = preg_replace_callback(
'/&#(\\d+);/', [$this,
'chr'], $strQuery);
119 $bTagsSearch =
false;
122 if (!array_key_exists(
'STEMMING', $aParamsEx))
124 $aParamsEx[
'STEMMING'] = COption::GetOptionString(
'search',
'use_stemming') ==
'Y';
127 if ($this->_opt_NO_WORD_LOGIC)
129 $this->Query->no_bool_lang =
true;
131 $query = $this->Query->GetQueryString(
'sct.SEARCHABLE_CONTENT', $strQuery, $bTagsSearch, $aParamsEx[
'STEMMING'], $this->_opt_ERROR_ON_EMPTY_STEM);
133 $fullTextParams = $aParamsEx;
134 if (!isset($fullTextParams[
'LIMIT']))
146 if ($this->errorno > 0)
161 $this->error = $this->Query->error;
162 $this->errorno = $this->Query->errorno;
167 if (mb_strlen(
$query) > 2000)
191 $this->url_add_params[] = $r;
201 !empty($this->Query->m_stemmed_words_id)
202 && is_array($this->Query->m_stemmed_words_id)
203 && array_sum($this->Query->m_stemmed_words_id) === 0
207 $r->InitFromArray([]);
211 $this->strSqlWhere =
'';
215 if (is_array($aParamsEx) && !empty($aParamsEx))
217 foreach ($aParamsEx as $aParamEx)
226 if (!empty($arSqlWhere))
229 "\n\t\t\t\t(" . implode(
")\n\t\t\t\t\tOR(", $arSqlWhere) .
"\n\t\t\t\t)",
239 $strSqlOrder = $this->
__PrepareSort($aSort,
'sc.', $bTagsCloud);
241 if (!array_key_exists(
'USE_TF_FILTER', $aParamsEx))
243 $aParamsEx[
'USE_TF_FILTER'] = COption::GetOptionString(
'search',
'use_tf_cache') ==
'Y';
246 $bStem = !$bTagsSearch &&
count($this->Query->m_stemmed_words) > 0;
248 if ($bStem &&
count($this->Query->m_stemmed_words))
254 if (!$bTagsCloud && $aParamsEx[
'USE_TF_FILTER'])
257 foreach ($this->Query->m_stemmed_words as
$i => $stem)
259 if (!array_key_exists($stem, $arStat))
266 $hwm = $arStat[$stem][
'TF'];
268 elseif ($hwm > $arStat[$stem][
'TF'])
270 $hwm = $arStat[$stem][
'TF'];
276 $arSqlWhere[] =
'st.TF >= ' . number_format($hwm, 2,
'.',
'');
277 $this->tf_hwm = $hwm;
282 if (!empty($arSqlWhere))
284 $this->strSqlWhere =
"\n\t\t\t\tAND (\n\t\t\t\t\t(" . implode(
")\n\t\t\t\t\tAND(", $arSqlWhere) .
")\n\t\t\t\t)";
289 $strSql = $this->tagsMakeSQL(
$query, $this->strSqlWhere, $strSqlOrder, $bIncSites, $bStem, $aParamsEx[
'LIMIT']);
293 $strSql = $this->MakeSQL(
$query, $this->strSqlWhere, $strSqlOrder, $bIncSites, $bStem);
296 $r =
$DB->Query($strSql);
298 parent::__construct($r);
303 if (array_key_exists(
'ERROR_ON_EMPTY_STEM',
$arOptions))
305 $this->_opt_ERROR_ON_EMPTY_STEM =
$arOptions[
'ERROR_ON_EMPTY_STEM'] ===
true;
308 if (array_key_exists(
'NO_WORD_LOGIC',
$arOptions))
310 $this->_opt_NO_WORD_LOGIC =
$arOptions[
'NO_WORD_LOGIC'] ===
true;
321 $this->limit = (int)
$limit;
327 $sql = preg_replace(
"/(DATE_FROM|DATE_TO|DATE_CHANGE)(\\s+IS\\s+NOT\\s+NULL|\\s+IS\\s+NULL|\\s*[<>!=]+\\s*'.*?')/im",
'', $this->strSqlWhere);
328 return md5(
$perm . $sql . $this->strTags);
338 $DB = CDatabase::GetModuleConnection(
'search');
340 $sql_lang_id =
$DB->ForSQL($lang_id);
342 foreach ($arStem as $stem)
344 $sql_stem[] =
$DB->ForSQL($stem);
347 $limit = COption::GetOptionInt(
'search',
'max_result_size');
354 foreach ($arStem as $stem)
366 SELECT s.ID, s.STEM, FREQ, TF
367 FROM b_search_content_freq f
368 inner join b_search_stem s on s.ID = f.STEM
369 WHERE LANGUAGE_ID = '" . $sql_lang_id .
"'
370 AND s.STEM in ('" . implode(
"','", $sql_stem) .
"')
371 AND " . (
$site_id <> '' ?
"SITE_ID = '" . $sql_site_id .
"'" :
'SITE_ID IS NULL') .
'
375 $rs =
$DB->Query($strSql);
376 while (
$ar =
$rs->Fetch())
389 $arMissed[] =
$DB->ForSQL($stem);
393 if (
count($arMissed) > 0)
396 SELECT s.ID, s.STEM, floor(st.TF/100) BUCKET, sum(st.TF/10000) TF_SUM, count(*) STEM_COUNT
398 b_search_content_stem st
399 inner join b_search_stem s on s.ID = st.STEM
400 ' . (
$site_id <> '' ?
"INNER JOIN b_search_content_site scsite ON scsite.SEARCH_CONTENT_ID = st.SEARCH_CONTENT_ID AND scsite.SITE_ID = '" . $sql_site_id .
"'" :
'') .
"
401 WHERE st.LANGUAGE_ID = '" . $sql_lang_id .
"'
402 AND s.STEM in ('" . implode(
"','", $arMissed) .
"')
403 GROUP BY s.ID, s.STEM, floor(st.TF/100)
404 ORDER BY s.ID, s.STEM, floor(st.TF/100) DESC
407 $rs =
$DB->Query($strSql);
408 while (
$ar =
$rs->Fetch())
424 if (isset(
$ar[
'DO_INSERT']) &&
$ar[
'DO_INSERT'])
426 $FREQ = intval(defined(
'search_range_by_sum_tf') ?
$ar[
'TF_SUM'] :
$ar[
'STEM_COUNT']);
428 UPDATE b_search_content_freq
429 SET FREQ=' . $FREQ .
', TF=' . number_format(
$ar[
'TF'], 2,
'.',
'') .
"
430 WHERE LANGUAGE_ID='" . $sql_lang_id .
"'
431 AND " . (
$site_id <> '' ?
"SITE_ID = '" . $sql_site_id .
"'" :
'SITE_ID IS NULL') .
"
432 AND STEM='" .
$DB->ForSQL(
$ar[
'ID']) .
"'
434 $rsUpdate =
$DB->Query($strSql);
435 if ($rsUpdate->AffectedRowsCount() <= 0)
438 INSERT INTO b_search_content_freq
439 (STEM, LANGUAGE_ID, SITE_ID, FREQ, TF)
441 ('" .
$DB->ForSQL(
$ar[
'ID']) .
"', '" . $sql_lang_id .
"', " . (
$site_id <> '' ?
"'" . $sql_site_id .
"'" :
'NULL') .
', ' . $FREQ .
', ' . number_format(
$ar[
'TF'], 2,
'.',
'') .
')
443 $rsInsert =
$DB->Query($strSql,
true);
451 function Repl($strCond, $strType, $strWh)
453 $l = mb_strlen($strCond);
455 if ($this->Query->bStemming)
458 $pcreLettersClass =
'[' . $arStemInfo[
'pcre_letters'] .
']';
463 $strWhUpp = mb_strtoupper($strWh);
466 $strCondUpp = mb_strtoupper($strCond);
471 $pos = mb_strpos($strWhUpp, $strCondUpp, $pos);
476 preg_match(
'/^[0-9]+;/', mb_substr($strWh, $pos)) &&
477 preg_match(
'/^[0-9]+#&/', strrev(mb_substr($strWh, 0, $pos + mb_strlen($strCond))))
480 $pos = mb_strpos($strWhUpp, $strCondUpp, $pos + 1);
488 if ($strType ==
'STEM')
490 $lw = mb_strlen($strWhUpp);
491 for ($s = $pos; $s >= 0; $s--)
493 if (!preg_match(
'/' . $pcreLettersClass .
'/u', mb_substr($strWhUpp, $s, 1)))
499 for ($e = $pos; $e < $lw; $e++)
501 if (!preg_match(
'/' . $pcreLettersClass .
'/u', mb_substr($strWhUpp, $e, 1)))
507 $a =
stemming(mb_substr($strWhUpp, $s, $e - $s + 1), $this->Query->m_lang,
true);
508 foreach (
$a as $stem => $cnt)
510 if ($stem == $strCondUpp)
512 $strWh = mb_substr($strWh, 0, $pos) .
'%^%' . mb_substr($strWh, $pos, $e - $pos + 1) .
'%/^%' . mb_substr($strWh, $e + 1);
513 $strWhUpp = mb_substr($strWhUpp, 0, $pos) .
'%^%' . str_repeat(
' ', $e - $pos + 1) .
'%/^%' . mb_substr($strWhUpp, $e + 1);
514 $pos += 7 + $e - $pos + 1;
520 $strWh = mb_substr($strWh, 0, $pos) .
'%^%' . mb_substr($strWh, $pos,
$l) .
'%/^%' . mb_substr($strWh, $pos +
$l);
521 $strWhUpp = mb_substr($strWhUpp, 0, $pos) .
'%^%' . str_repeat(
' ',
$l) .
'%/^%' . mb_substr($strWhUpp, $pos +
$l);
525 }
while ($pos < mb_strlen($strWhUpp));
534 foreach ($this->Query->m_words as $v)
536 $v = mb_strtoupper($v);
538 if (mb_strpos($v,
'"') !==
false)
540 $words[str_replace(
'"',
'"', $v)] =
'KAV';
544 foreach ($this->Query->m_stemmed_words as $v)
546 $words[mb_strtoupper($v)] =
'STEM';
550 if ($this->Query->bStemming)
554 $a =
stemming($this->Query->m_query, $this->Query->m_lang,
true);
555 foreach (
$a as $stem => $cnt)
557 if (!preg_match(
'/cut[56]/i', $stem))
559 $words[$stem] =
'STEM';
562 $pcreLettersClass =
'[' . $arStemInfo[
'pcre_letters'] .
']';
567 $strUpp = mb_strtoupper(
$str);
568 $pcreLettersClass =
'';
571 $wordsCount =
count($words);
575 foreach ($words as $search =>
$type)
579 $pregMask =
'(?<!' . $pcreLettersClass .
')' . preg_quote($search,
'/') . $pcreLettersClass .
'*|' . $pregMask;
583 $pregMask = $pregMask .
'|' . preg_quote($search,
'/');
586 $pregMask = trim($pregMask,
'|');
593 if (preg_match_all(
'/(' . $pregMask .
')/iu', $strUpp,
$matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE))
598 if (isset($words[$oneCase[0][0]]))
600 $search = $oneCase[0][0];
604 $a =
stemming($oneCase[0][0], $this->Query->m_lang,
true);
605 foreach (
$a as $stem => $cnt)
607 if (isset($words[$stem]))
618 if (!isset($arPos[$search]))
620 $arPos[$search] =
$p;
625 $cc =
count($arPosW);
626 if ($cc >= $wordsCount)
629 while ($cc > $wordsCount)
631 array_shift($arPosW);
632 array_shift($arPosP);
636 if (
count(array_unique($arPosW)) == $wordsCount)
642 (max($arPosP) - min($arPosP)) < (max($arPosLast) - min($arPosLast))
646 $arPosLast = $arPosP;
662 $str_len = mb_strlen(
$str);
664 while (($pos_end < $str_len) && (mb_strpos(
" ,.\n\r", mb_substr(
$str, $pos_end, 1)) ===
false))
668 return mb_substr(
$str, 0, $pos_end) . ($pos_end < $str_len ?
'...' :
'');
673 $str_len = strlen(
$str);
677 for (
$i = 0;
$i < 2;
$i++)
681 foreach ($arPos as $pos_mid)
684 $pos_beg = $pos_mid -
$delta;
689 while (($pos_beg > 0) && (mb_strpos(
" ,.!?\n\r", substr(
$str, $pos_beg, 1)) ===
false))
695 $pos_end = $pos_mid +
$delta;
696 if ($pos_end > $str_len)
700 while (($pos_end < $str_len) && (mb_strpos(
" ,.!?\n\r", substr(
$str, $pos_end, 1)) ===
false))
705 if ($pos_beg <= $last_pos)
707 $arOtr[
count($arOtr) - 1][1] = $pos_end;
711 $arOtr[] = [$pos_beg, $pos_end];
714 $last_pos = $pos_end;
721 foreach ($arOtr as $borders)
723 $str_result .= ($borders[0] <= 0 ?
'' :
' ...')
724 . substr(
$str, $borders[0], $borders[1] - $borders[0] + 1)
725 . ($borders[1] >= $str_len ?
'' :
'... ');
728 foreach ($words as $search =>
$type)
730 $str_result = $this->
Repl($search,
$type, $str_result);
733 $str_result = str_replace(
'%/^%',
'</b>', str_replace(
'%^%',
'<b>', $str_result));
740 parent::NavStart($nPageSize,
$bShowAll, $iNumPage);
741 if (COption::GetOptionString(
'search',
'stat_phrase') ==
'Y')
743 $this->Statistic =
new CSearchStatistic($this->strQueryText, $this->strTagsText);
744 $this->Statistic->PhraseStat($this->NavRecordCount, $this->NavPageNomer);
745 if ($this->Statistic->phrase_id)
747 $this->url_add_params[] =
'sphrase_id=' . $this->Statistic->phrase_id;
755 $DB = CDatabase::GetModuleConnection(
'search');
757 $r = parent::Fetch();
759 if ($r && $this->formatter)
761 $r = $this->formatter->format($r);
764 return $this->
Fetch();
773 $rsSite = CSite::GetList(
'',
'', [
'ID' =>
$site_id]);
774 $arSite[
$site_id] = $rsSite->Fetch();
776 $r[
'DIR'] = $arSite[
$site_id][
'DIR'];
777 $r[
'SERVER_NAME'] = $arSite[
$site_id][
'SERVER_NAME'];
779 if (!empty($r[
'SITE_URL']))
781 $r[
'URL'] = $r[
'SITE_URL'];
784 if (isset($r[
'URL']) && mb_substr($r[
'URL'], 0, 1) ==
'=')
786 foreach (
GetModuleEvents(
'search',
'OnSearchGetURL',
true) as $arEvent)
796 $r[
'URL'] = str_replace(
797 [
'#LANG#',
'#SITE_DIR#',
'#SERVER_NAME#'],
798 [$r[
'DIR'], $r[
'DIR'], $r[
'SERVER_NAME']],
801 $r[
'URL'] = preg_replace(
"'(?<!:)/+'s",
'/', $r[
'URL']);
802 $r[
'URL_WO_PARAMS'] = $r[
'URL'];
804 $w = $this->Query->m_words;
805 if (
count($this->url_add_params))
807 $p1 = mb_strpos($r[
'URL'],
'?');
817 $p2 = mb_strpos($r[
'URL'],
'#', $p1);
820 $r[
'URL'] = $r[
'URL'] .
$ch . implode(
'&', $this->url_add_params);
824 $r[
'URL'] = mb_substr($r[
'URL'], 0, $p2) .
$ch . implode(
'&', $this->url_add_params) . mb_substr($r[
'URL'], $p2);
828 if (!array_key_exists(
'TITLE_FORMATED', $r) && array_key_exists(
'TITLE', $r))
831 $r[
'TITLE_FORMATED_TYPE'] =
'html';
833 if (!empty($r[
'BODY']))
836 $r[
'BODY_FORMATED_TYPE'] =
'html';
840 $max_body_size = COption::GetOptionInt(
'search',
'max_body_size');
841 $sqlBody = $max_body_size > 0 ?
'left(BODY,' . $max_body_size .
') as BODY' :
'BODY';
842 $rsBody =
$DB->Query(
'select ' . $sqlBody .
' from b_search_content where ID=' . $r[
'ID']);
843 if ($arBody = $rsBody->Fetch())
846 $r[
'BODY_FORMATED_TYPE'] =
'html';
857 static $SEARCH_MASKS_CACHE =
false;
859 if (!is_array($SEARCH_MASKS_CACHE))
861 $arSearch = [
'\\',
'.',
'?',
'*',
"'"];
862 $arReplace = [
'/',
'\\.',
'.',
'.*?',
"\\'"];
868 COption::GetOptionString(
'search',
'include_mask')
870 $arIncTmp = explode(
';', $inc);
871 foreach ($arIncTmp as $mask)
876 $arInc[] =
"'^" . $mask .
"$'";
885 COption::GetOptionString(
'search',
'exclude_mask')
887 $arExcTmp = explode(
';', $exc);
888 foreach ($arExcTmp as $mask)
893 if (preg_match(
'#^/[a-z0-9_.\\\\]+/#i', $mask))
895 $arFullExc[] =
"'^" . $mask .
"$'u";
899 $arExc[] =
"'^" . $mask .
"$'u";
904 $SEARCH_MASKS_CACHE = [
905 'full_exc' => $arFullExc,
911 $file = end(explode(
'/',
$path));
912 if (strncmp($file,
'.', 1) == 0)
917 foreach ($SEARCH_MASKS_CACHE[
'full_exc'] as $mask)
919 if (preg_match($mask,
$path))
925 foreach ($SEARCH_MASKS_CACHE[
'exc'] as $mask)
927 if (preg_match($mask,
$path))
933 foreach ($SEARCH_MASKS_CACHE[
'inc'] as $mask)
935 if (preg_match($mask,
$path))
946 static $SEARCH_CACHED_GROUPS =
false;
948 if (!is_array($SEARCH_CACHED_GROUPS))
950 $SEARCH_CACHED_GROUPS = [];
952 while ($g = $db_groups->Fetch())
954 $group_id = intval($g[
'ID']);
957 $SEARCH_CACHED_GROUPS[$group_id] = $group_id;
962 return $SEARCH_CACHED_GROUPS;
967 $SITE = COption::GetOptionString(
'search',
'mnogosearch_url',
'www.mnogosearch.org');
968 $PATH = COption::GetOptionString(
'search',
'mnogosearch_path',
'');
969 $PORT = COption::GetOptionString(
'search',
'mnogosearch_port',
'80');
971 $QUERY_STR =
'document=' . urlencode($xml);
973 $strRequest =
'POST ' . $PATH .
" HTTP/1.0\r\n";
974 $strRequest .=
"User-Agent: BitrixSM\r\n";
975 $strRequest .=
"Accept: */*\r\n";
976 $strRequest .=
'Host: ' . $SITE .
"\r\n";
977 $strRequest .=
"Accept-Language: en\r\n";
978 $strRequest .=
"Content-type: application/x-www-form-urlencoded\r\n";
979 $strRequest .=
'Content-length: ' . mb_strlen($QUERY_STR) .
"\r\n";
980 $strRequest .=
"\r\n";
981 $strRequest .= $QUERY_STR;
982 $strRequest .=
"\r\n";
988 $FP = fsockopen($SITE, $PORT, $errno, $errstr, 120);
991 fputs($FP, $strRequest);
993 while (($line = fgets($FP, 4096)) && $line !=
"\r\n");
994 while ($line = fread($FP, 4096))
1011 $DB = CDatabase::GetModuleConnection(
'search');
1021 $NS = [
'CLEAR' =>
'N',
'MODULE' =>
'',
'ID' =>
'',
'SESS_ID' => md5(uniqid(
''))];
1022 if ($NS_OLD[
'SITE_ID'] !=
'')
1024 $NS[
'SITE_ID'] = $NS_OLD[
'SITE_ID'];
1026 if ($NS_OLD[
'MODULE_ID'] !=
'')
1028 $NS[
'MODULE_ID'] = $NS_OLD[
'MODULE_ID'];
1031 $NS[
'CNT'] = intval(
$NS[
'CNT']);
1032 if (!$bFull && (!isset(
$NS[
'SESS_ID']) || mb_strlen(
$NS[
'SESS_ID']) != 32))
1034 $NS[
'SESS_ID'] = md5(uniqid(
''));
1037 $p1 = microtime(
true);
1039 $DB->StartTransaction();
1042 if (!isset(
$NS[
'CLEAR']) ||
$NS[
'CLEAR'] !=
'Y')
1046 foreach (
GetModuleEvents(
'search',
'OnBeforeFullReindexClear',
true) as $arEvent)
1052 $DB->Query(
'TRUNCATE TABLE b_search_content_param');
1053 $DB->Query(
'TRUNCATE TABLE b_search_content_site');
1054 $DB->Query(
'TRUNCATE TABLE b_search_content_right');
1055 $DB->Query(
'TRUNCATE TABLE b_search_content_title');
1056 $DB->Query(
'TRUNCATE TABLE b_search_tags');
1057 $DB->Query(
'TRUNCATE TABLE b_search_content_freq');
1058 $DB->Query(
'TRUNCATE TABLE b_search_content');
1059 $DB->Query(
'TRUNCATE TABLE b_search_suggest');
1060 $DB->Query(
'TRUNCATE TABLE b_search_user_right');
1066 $DB->Query(
'TRUNCATE TABLE b_search_suggest');
1067 $DB->Query(
'TRUNCATE TABLE b_search_user_right');
1068 $DB->Query(
'TRUNCATE TABLE b_search_content_freq');
1077 (!isset(
$NS[
'MODULE']) ||
$NS[
'MODULE'] ==
'' ||
$NS[
'MODULE'] ==
'main')
1078 && (!isset(
$NS[
'MODULE_ID']) ||
$NS[
'MODULE_ID'] ==
'' ||
$NS[
'MODULE_ID'] ==
'main')
1083 if (isset(
$NS[
'SITE_ID']) &&
$NS[
'SITE_ID'] !=
'')
1088 while ($arR = $r->Fetch())
1090 $path = rtrim($arR[
'DIR'],
'/');
1100 if (
$path == $path2)
1104 if (mb_substr(
$path, 0, mb_strlen($path2)) == $path2)
1111 foreach ($dub as
$p)
1119 $path = rtrim($arR[
'DIR'],
'/');
1124 && isset(
$NS[
'MODULE'])
1125 &&
$NS[
'MODULE'] ==
'main'
1126 && mb_substr(
$NS[
'ID'] .
'/', 0, mb_strlen($site_path)) != $site_path
1136 &&
$NS[
'MODULE'] <>
''
1145 $p1 = microtime(
true);
1153 isset(
$NS[
'MODULE_ID'])
1154 &&
$NS[
'MODULE_ID'] !=
''
1155 &&
$NS[
'MODULE_ID'] != $arEvent[
'TO_MODULE_ID']
1162 && isset(
$NS[
'MODULE'])
1163 &&
$NS[
'MODULE'] <>
''
1164 &&
$NS[
'MODULE'] !=
'main'
1165 &&
$NS[
'MODULE'] != $arEvent[
'TO_MODULE_ID']
1171 $oCallBack->MODULE = $arEvent[
'TO_MODULE_ID'];
1172 $oCallBack->CNT = &
$NS[
'CNT'];
1173 $oCallBack->SESS_ID =
$NS[
'SESS_ID'] ??
'';
1195 'MODULE' => $arEvent[
'TO_MODULE_ID'],
1196 'CNT' => $oCallBack->CNT,
1198 'CLEAR' =>
$NS[
'CLEAR'],
1199 'SESS_ID' =>
$NS[
'SESS_ID'],
1200 'SITE_ID' =>
$NS[
'SITE_ID'],
1201 'MODULE_ID' =>
$NS[
'MODULE_ID'],
1225 $NS = [
'CLEAR' =>
'N',
'MODULE' =>
'',
'ID' =>
'',
'SESS_ID' => md5(uniqid(
''))];
1229 if ($arEvent[
'TO_MODULE_ID'] != $MODULE_ID)
1235 $oCallBack->MODULE = $arEvent[
'TO_MODULE_ID'];
1236 $oCallBack->CNT = &
$NS[
'CNT'];
1237 $oCallBack->SESS_ID =
$NS[
'SESS_ID'];
1256 return [
'MODULE' => $arEvent[
'TO_MODULE_ID'],
'CNT' => $oCallBack->CNT,
'ID' =>
$arResult,
'CLEAR' =>
$NS[
'CLEAR'],
'SESS_ID' =>
$NS[
'SESS_ID']];
1268 $DB = CDatabase::GetModuleConnection(
'search');
1269 $rs =
$DB->Query(
"select * from b_search_content where MODULE_ID = '" .
$DB->ForSql($MODULE_ID) .
"' and ITEM_ID = '" .
$DB->ForSql($ITEM_ID) .
"'");
1277 $rs =
$DB->Query(
'select * from b_search_content_site where SEARCH_CONTENT_ID = ' .
$DB->ForSql(
$arFields[
'ID']));
1278 while (
$ar =
$rs->Fetch())
1284 $rs =
$DB->Query(
'select * from b_search_content_right where SEARCH_CONTENT_ID = ' .
$DB->ForSql(
$arFields[
'ID']));
1285 while (
$ar =
$rs->Fetch())
1291 $rs =
$DB->Query(
'select * from b_search_content_param where SEARCH_CONTENT_ID = ' .
$DB->ForSql(
$arFields[
'ID']));
1292 while (
$ar =
$rs->Fetch())
1302 public static function Index($MODULE_ID, $ITEM_ID,
$arFields, $bOverWrite =
false, $SEARCH_SESS_ID =
'')
1304 $DB = CDatabase::GetModuleConnection(
'search');
1311 if (is_array($arEventResult))
1319 $bTitle = array_key_exists(
'TITLE',
$arFields);
1324 $bBody = array_key_exists(
'BODY',
$arFields);
1329 $bTags = array_key_exists(
'TAGS',
$arFields);
1340 if (array_key_exists(
'SITE_ID',
$arFields))
1352 if (
'' .
$k !=
'' .
$i)
1363 foreach ($x as
$val)
1386 FROM b_search_custom_rank CR
1387 WHERE CR.SITE_ID in ('" . implode(
"', '",
$arSites) .
"')
1388 AND CR.MODULE_ID='" .
$DB->ForSQL($MODULE_ID) .
"'
1389 " . (
is_set(
$arFields,
'PARAM1') ?
"AND (CR.PARAM1 IS NULL OR CR.PARAM1='' OR CR.PARAM1='" .
$DB->ForSQL(
$arFields[
'PARAM1']) .
"')" :
'') .
'
1390 ' . (
is_set(
$arFields,
'PARAM2') ?
"AND (CR.PARAM2 IS NULL OR CR.PARAM2='' OR CR.PARAM2='" .
$DB->ForSQL(
$arFields[
'PARAM2']) .
"')" :
'') .
'
1391 ' . ($ITEM_ID <>
'' ?
"AND (CR.ITEM_ID IS NULL OR CR.ITEM_ID='' OR CR.ITEM_ID='" .
$DB->ForSQL($ITEM_ID) .
"')" :
'') .
'
1393 PARAM1 DESC, PARAM2 DESC, ITEM_ID DESC
1395 $r =
$DB->Query($strSql);
1406 foreach (
$arFields[
'PERMISSIONS'] as $group_id)
1408 if (is_numeric($group_id))
1410 $arGroups[$group_id] =
'G' . intval($group_id);
1422 $strSqlSelect .=
',BODY';
1426 $strSqlSelect .=
',TITLE';
1430 $strSqlSelect .=
',TAGS';
1434 'SELECT ID, MODULE_ID, ITEM_ID, ' .
$DB->DateToCharFunction(
'DATE_CHANGE') .
' as DATE_CHANGE
1435 ' . $strSqlSelect .
"
1436 FROM b_search_content
1437 WHERE MODULE_ID = '" .
$DB->ForSQL($MODULE_ID) .
"'
1438 AND ITEM_ID = '" .
$DB->ForSQL($ITEM_ID) .
"' ";
1440 $r =
$DB->Query($strSql);
1448 foreach (
GetModuleEvents(
'search',
'OnBeforeIndexDelete',
true) as $arEvent)
1455 $DB->Query(
'DELETE FROM b_search_content_param WHERE SEARCH_CONTENT_ID = ' .
$ID);
1456 $DB->Query(
'DELETE FROM b_search_content_right WHERE SEARCH_CONTENT_ID = ' .
$ID);
1457 $DB->Query(
'DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ' .
$ID);
1458 $DB->Query(
'DELETE FROM b_search_content_title WHERE SEARCH_CONTENT_ID = ' .
$ID);
1459 $DB->Query(
'DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ' .
$ID);
1461 $DB->Query(
'DELETE FROM b_search_content WHERE ID = ' .
$ID);
1481 if (array_key_exists(
'LAST_MODIFIED',
$arFields))
1487 $arFields[
'~DATE_CHANGE'] =
$arFields[
'DATE_CHANGE'] = $DATE_CHANGE =
$DB->FormatDate(
$arFields[
'DATE_CHANGE'],
'DD.MM.YYYY HH:MI:SS', CLang::GetDateFormat());
1494 if (!$bOverWrite && $DATE_CHANGE ==
$arResult[
'DATE_CHANGE'])
1496 if ($SEARCH_SESS_ID <>
'')
1498 $DB->Query(
"UPDATE b_search_content SET UPD='" .
$DB->ForSql($SEARCH_SESS_ID) .
"' WHERE ID = " .
$ID);
1507 if ($bBody || $bTitle || $bTags)
1509 if (array_key_exists(
'INDEX_TITLE',
$arFields) &&
$arFields[
'INDEX_TITLE'] ===
false)
1543 $content = preg_replace_callback(
'/&#(\\d+);/', [
'CSearch',
'chr'],
$content);
1547 if ($SEARCH_SESS_ID <>
'')
1552 if (array_key_exists(
'TITLE',
$arFields))
1555 !array_key_exists(
'INDEX_TITLE',
$arFields)
1566 $DB->Query(
'DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ' .
$ID);
1570 foreach (
GetModuleEvents(
'search',
'OnBeforeIndexUpdate',
true) as $arEvent)
1596 if (array_key_exists(
'INDEX_TITLE',
$arFields) &&
$arFields[
'INDEX_TITLE'] ===
false)
1605 $content = preg_replace_callback(
'/&#(\\d+);/', [
'CSearch',
'chr'],
$content);
1608 if ($SEARCH_SESS_ID !=
'')
1618 $strSql =
"SELECT ID FROM b_search_content WHERE MODULE_ID = '" .
$DB->ForSQL($MODULE_ID) .
"' AND ITEM_ID = '" .
$DB->ForSQL($ITEM_ID) .
"' ";
1619 $rs =
$DB->Query($strSql);
1632 foreach (
GetModuleEvents(
'search',
'OnAfterIndexAdd',
true) as $arEvent)
1647 !array_key_exists(
'INDEX_TITLE',
$arFields)
1665 static $arAllEntities = [
1667 '&IQUEST;',
'&AGRAVE;',
'&AACUTE;',
'&ACIRC;',
'&ATILDE;',
1668 '&AUML;',
'&ARING;',
'&AELIG;',
'&CCEDIL;',
'&EGRAVE;',
1669 '&EACUTE;',
'&ECIRC;',
'&EUML;',
'&IGRAVE;',
'&IACUTE;',
1670 '&ICIRC;',
'&IUML;',
'Ð',
'&NTILDE;',
'&OGRAVE;',
1671 '&OACUTE;',
'&OCIRC;',
'&OTILDE;',
'&OUML;',
'&TIMES;',
1672 '&OSLASH;',
'&UGRAVE;',
'&UACUTE;',
'&UCIRC;',
'&UUML;',
1673 '&YACUTE;',
'Þ',
'&SZLIG;',
'&AGRAVE;',
'&AACUTE;',
1674 '&ACIRC;',
'&ATILDE;',
'&AUML;',
'&ARING;',
'&AELIG;',
1675 '&CCEDIL;',
'&EGRAVE;',
'&EACUTE;',
'&ECIRC;',
'&EUML;',
1676 '&IGRAVE;',
'&IACUTE;',
'&ICIRC;',
'&IUML;',
'Ð',
1677 '&NTILDE;',
'&OGRAVE;',
'&OACUTE;',
'&OCIRC;',
'&OTILDE;',
1678 '&OUML;',
'&DIVIDE;',
'&OSLASH;',
'&UGRAVE;',
'&UACUTE;',
1679 '&UCIRC;',
'&UUML;',
'&YACUTE;',
'Þ',
'&YUML;',
1680 '&OELIG;',
'&OELIG;',
'&SCARON;',
'&SCARON;',
'&YUML;',
1683 '&ALPHA;',
'&BETA;',
'&GAMMA;',
'&DELTA;',
'&EPSILON;',
1684 '&ZETA;',
'&ETA;',
'&THETA;',
'&IOTA;',
'&KAPPA;',
1685 '&LAMBDA;',
'&MU;',
'&NU;',
'&XI;',
'&OMICRON;',
1686 '&PI;',
'&RHO;',
'&SIGMA;',
'&TAU;',
'&UPSILON;',
1687 '&PHI;',
'&CHI;',
'&PSI;',
'&OMEGA;',
'&ALPHA;',
1688 '&BETA;',
'&GAMMA;',
'&DELTA;',
'&EPSILON;',
'&ZETA;',
1689 '&ETA;',
'&THETA;',
'&IOTA;',
'&KAPPA;',
'&LAMBDA;',
1690 '&MU;',
'&NU;',
'&XI;',
'&OMICRON;',
'&PI;',
1691 '&RHO;',
'&SIGMAF;',
'&SIGMA;',
'&TAU;',
'&UPSILON;',
1692 '&PHI;',
'&CHI;',
'&PSI;',
'&OMEGA;',
'&THETASYM;',
1696 '&IEXCL;',
'&CENT;',
'&POUND;',
'&CURREN;',
'&YEN;',
1697 '&BRVBAR;',
'&SECT;',
'&UML;',
'©',
'&ORDF;',
1698 '&LAQUO;',
'&NOT;',
'®',
'&MACR;',
'&DEG;',
1699 '&PLUSMN;',
'&SUP2;',
'&SUP3;',
'&ACUTE;',
'&MICRO;',
1700 '&PARA;',
'&MIDDOT;',
'&CEDIL;',
'&SUP1;',
'&ORDM;',
1701 '&RAQUO;',
'&FRAC14;',
'&FRAC12;',
'&FRAC34;',
'&CIRC;',
1702 '&TILDE;',
'&ENSP;',
'&EMSP;',
'&THINSP;',
'&ZWNJ;',
1703 '&ZWJ;',
'&LRM;',
'&RLM;',
'&NDASH;',
'&MDASH;',
1704 '&LSQUO;',
'&RSQUO;',
'&SBQUO;',
'&LDQUO;',
'&RDQUO;',
1705 '&BDQUO;',
'&DAGGER;',
'&DAGGER;',
'&PERMIL;',
'&LSAQUO;',
1706 '&RSAQUO;',
'&EURO;',
'&BULL;',
'&HELLIP;',
'&PRIME;',
1707 '&PRIME;',
'&OLINE;',
'&FRASL;',
'&WEIERP;',
'&IMAGE;',
1708 '&REAL;',
'™',
'&ALEFSYM;',
'&LARR;',
'&UARR;',
1709 '&RARR;',
'&DARR;',
'&HARR;',
'&CRARR;',
'&LARR;',
1710 '&UARR;',
'&RARR;',
'&DARR;',
'&HARR;',
'&FORALL;',
1711 '&PART;',
'&EXIST;',
'&EMPTY;',
'&NABLA;',
'&ISIN;',
1712 '&NOTIN;',
'&NI;',
'&PROD;',
'&SUM;',
'&MINUS;',
1713 '&LOWAST;',
'&RADIC;',
'&PROP;',
'&INFIN;',
'&ANG;',
1714 '&AND;',
'&OR;',
'&CAP;',
'&CUP;',
'&INT;',
1715 '&THERE4;',
'&SIM;',
'&CONG;',
'&ASYMP;',
'&NE;',
1716 '&EQUIV;',
'&LE;',
'&GE;',
'&SUB;',
'&SUP;',
1717 '&NSUB;',
'&SUBE;',
'&SUPE;',
'&OPLUS;',
'&OTIMES;',
1718 '&PERP;',
'&SDOT;',
'&LCEIL;',
'&RCEIL;',
'&LFLOOR;',
1719 '&RFLOOR;',
'&LANG;',
'&RANG;',
'&LOZ;',
'&SPADES;',
1720 '&CLUBS;',
'&HEARTS;',
'&DIAMS;',
1723 static $pregEntities =
false;
1727 foreach ($arAllEntities as
$key => $entities)
1729 $pregEntities[
$key] = implode(
'|', $entities);
1732 return preg_replace(
'/(' . implode(
'|', $pregEntities) .
')/i',
'',
$str);
1739 $DB = CDatabase::GetModuleConnection(
'search');
1741 if (!is_array(
$path))
1746 $file_doc_root = CSite::GetSiteDocRoot(
$path[0]);
1747 $file_rel_path =
$path[1];
1748 $file_abs_path = preg_replace(
'#[\\\\\\/]+#',
'/', $file_doc_root .
'/' . $file_rel_path);
1749 $f =
$io->GetFile($file_abs_path);
1751 if (!
$f->IsExists() || !
$f->IsReadable())
1761 $max_file_size = COption::GetOptionInt(
'search',
'max_file_size', 0);
1764 &&
$f->GetFileSize() > ($max_file_size * 1024)
1771 $rsSites = CSite::GetList(
'lendir',
'desc');
1772 while ($arSite =
$rsSites->Fetch())
1774 $site_path = preg_replace(
'#[\\\\\\/]+#',
'/', $arSite[
'ABS_DOC_ROOT'] .
'/' . $arSite[
'DIR'] .
'/');
1775 if (mb_strpos($file_abs_path, $site_path) === 0)
1777 $file_site = $arSite[
'ID'];
1782 if ($file_site ==
'')
1787 $item_id = $file_site .
'|' . $file_rel_path;
1788 if (mb_strlen($item_id) > 255)
1793 if ($SEARCH_SESS_ID <>
'')
1795 $DATE_CHANGE =
$DB->CharToDateFunction(
1797 $DB->DateFormatToPHP(CLang::GetDateFormat(
'FULL')),
$f->GetModificationTime() + CTimeZone::GetOffset()
1802 FROM b_search_content
1803 WHERE MODULE_ID = 'main'
1804 AND ITEM_ID = '" .
$DB->ForSQL($item_id) .
"'
1805 AND DATE_CHANGE = " . $DATE_CHANGE .
'
1808 $r =
$DB->Query($strSql);
1809 if ($arR = $r->Fetch())
1811 $strSql =
"UPDATE b_search_content SET UPD='" .
$DB->ForSQL($SEARCH_SESS_ID) .
"' WHERE ID = " . $arR[
'ID'];
1812 $DB->Query($strSql);
1818 foreach (
GetModuleEvents(
'search',
'OnSearchGetFileContent',
true) as $arEvent)
1825 if (!is_array($arrFile))
1828 $sHeadEndPos = mb_strpos($sFile,
'</head>');
1829 if ($sHeadEndPos ===
false)
1831 $sHeadEndPos = mb_strpos($sFile,
'</HEAD>');
1833 if ($sHeadEndPos !==
false)
1837 if (preg_match(
"/<(meta)\\s+([^>]*)(content)\\s*=\\s*(['\"]).*?(charset)\\s*=\\s*(.*?)(\\4)/is", mb_substr($sFile, 0, $sHeadEndPos), $arMetaMatch))
1839 $doc_charset = $arMetaMatch[6];
1840 if (strtoupper($doc_charset) !=
'UTF-8')
1850 $title = mb_convert_encoding(
$title,
'UTF-8',
'UTF-8');
1863 $p =
$APPLICATION->GetFileAccessPermission([$file_site, $file_rel_path], [$group_id]);
1866 $arGPerm[] = $group_id;
1874 $tags = COption::GetOptionString(
'search',
'page_tag_property');
1879 'SITE_ID' => $file_site,
1880 'DATE_CHANGE' => date(
'd.m.Y H:i:s',
$f->GetModificationTime() + 1),
1883 'URL' => $file_rel_path,
1884 'PERMISSIONS' => $arGPerm,
1887 'TAGS' => array_key_exists($tags, $arrFile[
'PROPERTIES']) ? $arrFile[
'PROPERTIES'][$tags] :
'',
1888 ],
false, $SEARCH_SESS_ID
1896 if (!is_array(
$path))
1915 if (!
$f->IsReadable())
1921 foreach ($d->GetChildren() as $dir_entry)
1923 $path_file =
$path .
'/' . $dir_entry->GetName();
1925 if ($dir_entry->IsDirectory())
1927 if ($path_file ==
'/bitrix')
1935 || !isset(
$NS[
'MODULE'])
1936 ||
$NS[
'MODULE'] ==
''
1938 $NS[
'MODULE'] ==
'main'
1939 && mb_substr(
$NS[
'ID'] .
'/', 0, mb_strlen(
$site .
'|' . $path_file .
'/')) ==
$site .
'|' . $path_file .
'/'
1961 && isset(
$NS[
'MODULE'])
1962 &&
$NS[
'MODULE'] <>
''
1963 &&
$NS[
'MODULE'] ==
'main'
1964 &&
$NS[
'ID'] ==
$site .
'|' . $path_file
1972 if (intval(
$ID) > 0)
1974 $NS[
'CNT'] = intval(
$NS[
'CNT']) + 1;
1982 $NS[
'MODULE'] =
'main';
1983 $NS[
'ID'] =
$site .
'|' . $path_file;
1996 $a = preg_split(
'/(<' .
'\\?|\\?' .
'>|\\/\\' .
'*|\\' .
'*' .
'\\/|\\/\\/|\'|"|\\n)/',
$str, -1, PREG_SPLIT_DELIM_CAPTURE);
2002 if (
$a[
$i] ==
'\'' && $bPHP)
2006 if (
$a[
$i] ===
'\'')
2009 if (preg_match(
'/(\\\\+)$/',
$a[
$i - 1], $m))
2011 if ((mb_strlen($m[1]) % 2) == 0)
2030 if (preg_match(
'/(\\\\+)$/',
$a[
$i - 1], $m))
2032 if ((mb_strlen($m[1]) % 2) == 0)
2050 if (
$a[
$i] ===
"\n" ||
$a[
$i] ===
'?>')
2061 if (
$a[
$i] ===
'*/')
2098 "'<script[^>]*?>.*?</script>'si",
2099 "'<style[^>]*?>.*?</style>'si",
2100 "'<select[^>]*?>.*?</select>'si",
2101 "'<head[^>]*?>.*?</head>'si",
2104 "'([\\r\\n])[\\s]+'",
2130 $str = preg_replace($search, $replace,
$str);
2142 $DB = CDatabase::GetModuleConnection(
'search');
2144 DELETE FROM b_search_content_right
2145 WHERE GROUP_CODE = 'G" . intval(
$ID) .
"'
2151 $DB = CDatabase::GetModuleConnection(
'search');
2154 static $arFilterEvents =
false;
2163 $field = mb_strtoupper($field);
2168 && $field !==
'PARAMS'
2176 if (
$val !==
false &&
$val !==
'no')
2178 $arNewFilter[$field] =
$val;
2182 if (
$val !==
false &&
$val !==
'no')
2184 $arNewFilter[
'=' . $field] =
$val;
2192 $arNewFilter[
'=' . $field] =
$val;
2198 $time = ConvertTimeStamp(time() + CTimeZone::GetOffset(),
'FULL');
2203 '=DATE_FROM' =>
false,
2204 '<=DATE_FROM' =>
$time,
2208 '=DATE_TO' =>
false,
2209 '>=DATE_TO' =>
$time,
2217 $arNewFilter[
'>=' . $field] =
$val;
2223 $arNewFilter[
'=' . $field] =
$val;
2227 if (!is_array($arFilterEvents))
2229 $arFilterEvents = [];
2230 foreach (
GetModuleEvents(
'search',
'OnSearchPrepareFilter',
true) as $arEvent)
2232 $arFilterEvents[] = $arEvent;
2237 foreach ($arFilterEvents as $arEvent)
2242 $arSql[] =
'(' . $sql .
')';
2249 $arNewFilter[$field] =
$val;
2254 $strSearchContentAlias = rtrim($strSearchContentAlias,
'.');
2259 'TABLE_ALIAS' => $strSearchContentAlias,
2260 'FIELD_NAME' => $strSearchContentAlias .
'.MODULE_ID',
2262 'FIELD_TYPE' =>
'string',
2266 'TABLE_ALIAS' => $strSearchContentAlias,
2267 'FIELD_NAME' => $strSearchContentAlias .
'.ITEM_ID',
2269 'FIELD_TYPE' =>
'string',
2273 'TABLE_ALIAS' => $strSearchContentAlias,
2274 'FIELD_NAME' => $strSearchContentAlias .
'.PARAM1',
2276 'FIELD_TYPE' =>
'string',
2280 'TABLE_ALIAS' => $strSearchContentAlias,
2281 'FIELD_NAME' => $strSearchContentAlias .
'.PARAM2',
2283 'FIELD_TYPE' =>
'string',
2287 'TABLE_ALIAS' => $strSearchContentAlias,
2288 'FIELD_NAME' => $strSearchContentAlias .
'.DATE_FROM',
2290 'FIELD_TYPE' =>
'datetime',
2294 'TABLE_ALIAS' => $strSearchContentAlias,
2295 'FIELD_NAME' => $strSearchContentAlias .
'.DATE_TO',
2297 'FIELD_TYPE' =>
'datetime',
2301 'TABLE_ALIAS' => $strSearchContentAlias,
2302 'FIELD_NAME' => $strSearchContentAlias .
'.DATE_CHANGE',
2304 'FIELD_TYPE' =>
'datetime',
2308 'TABLE_ALIAS' =>
'scsite',
2309 'FIELD_NAME' =>
'scsite.SITE_ID',
2311 'FIELD_TYPE' =>
'string',
2315 'TABLE_ALIAS' =>
'scsite',
2316 'FIELD_NAME' =>
'scsite.URL',
2318 'FIELD_TYPE' =>
'string',
2322 'TABLE_ALIAS' => $strSearchContentAlias,
2323 'FIELD_NAME' => $strSearchContentAlias .
'.URL',
2325 'FIELD_TYPE' =>
'callback',
2326 'CALLBACK' => [$obWhereHelp,
'_CallbackURL'],
2330 'TABLE_ALIAS' => $strSearchContentAlias,
2331 'FIELD_NAME' => $strSearchContentAlias .
'.ID',
2333 'FIELD_TYPE' =>
'callback',
2334 'CALLBACK' => [$obWhereHelp,
'_CallbackPARAMS'],
2339 $strWhere = $obQueryWhere->GetQuery($arNewFilter);
2341 if (
count($arSql) > 0)
2345 $strWhere .=
"\nAND (" . implode(
' AND ', $arSql) .
')';
2349 $strWhere = implode(
"\nAND ", $arSql);
2353 $bIncSites = $bIncSites || $obQueryWhere->GetJoins() <>
'';
2357 function __PrepareSort($aSort = [], $strSearchContentAlias =
'sc.', $bTagsCloud =
false)
2359 $DB = CDatabase::GetModuleConnection(
'search');
2360 $helper =
$DB->getConnection()->getSqlHelper();
2363 if (!is_array($aSort))
2365 $aSort = [$aSort =>
'ASC'];
2370 foreach ($aSort as
$key => $ord)
2372 $ord = mb_strtoupper($ord) <>
'ASC' ?
'DESC' :
'ASC';
2377 $arOrder[] =
'DC_TMP ' . $ord;
2381 $arOrder[] =
$key .
' ' . $ord;
2385 if (
count($arOrder) == 0)
2387 $arOrder[] =
'NAME ASC';
2392 $this->flagsUseRatingSort = 0;
2393 foreach ($aSort as
$key => $ord)
2395 $ord = mb_strtoupper($ord) <>
'ASC' ?
'DESC' :
'ASC';
2400 if (!($this->flagsUseRatingSort & 0x01))
2402 $this->flagsUseRatingSort = 0x02;
2404 $arOrder[] = $strSearchContentAlias .
$key .
' ' . $ord;
2407 if (!($this->flagsUseRatingSort & 0x02))
2409 $this->flagsUseRatingSort = 0x01;
2411 $arOrder[] = $helper->quote(
'RANK') .
' ' . $ord;
2415 $arOrder[] =
$key .
' ' . $ord;
2427 if (!($this->flagsUseRatingSort & 0x01))
2429 $this->flagsUseRatingSort = 0x02;
2431 $arOrder[] =
$key .
' ' . $ord;
2436 if (
count($arOrder) == 0)
2438 $arOrder[] =
'CUSTOM_RANK DESC';
2439 $arOrder[] = $helper->quote(
'RANK') .
' DESC';
2440 $arOrder[] = $strSearchContentAlias .
'DATE_CHANGE DESC';
2441 $this->flagsUseRatingSort = 0x01;
2445 return ' ORDER BY ' . implode(
', ', $arOrder);
2450 $DB = CDatabase::GetModuleConnection(
'search');
2451 $helper =
$DB->getConnection()->getSqlHelper();
2453 if (array_key_exists(
'~DATE_CHANGE',
$arFields))
2465 $arFields[
'DATE_CHANGE'] =
$DB->FormatDate(
$arFields[
'DATE_CHANGE'],
'DD.MM.YYYY HH:MI:SS', CLang::GetDateFormat());
2469 foreach (
$DB->GetTableFields(
'b_search_content') as $field)
2471 $tableFields[$field[
'NAME']] = $field[
'TYPE'];
2476 $search = str_ends_with($fieldName,
'~') ? mb_substr($fieldName, 0, -1) : $fieldName;
2477 if (!isset($tableFields[$search]))
2505 unset($update[
'MODULE_ID']);
2506 unset($update[
'ITEM_ID']);
2508 $merge = $helper->prepareMerge(
'b_search_content', [
'MODULE_ID',
'ITEM_ID'],
$arFields, $update);
2509 if ($merge && $merge[0])
2511 $DB->Query($merge[0]);
2514 $ar =
$DB->Query(
'SELECT ID FROM b_search_content WHERE MODULE_ID=\'' .
$DB->ForSql(
$arFields[
'MODULE_ID']) .
'\' AND ITEM_ID=\
'' .
$DB->ForSql(
$arFields[
'ITEM_ID']) .
'\'')->Fetch();
2516 return $ar ?
$ar[
'ID'] :
false;
2523 $DB = CDatabase::GetModuleConnection(
'search');
2534 if (!array_key_exists(2, $permission) && array_key_exists(
'*', $permission))
2536 $permission[2] = $permission[
'*'];
2538 if (!is_array($old_permission))
2540 $old_permission = [];
2542 if (!array_key_exists(2, $old_permission) && array_key_exists(
'*', $old_permission))
2544 $old_permission[2] = $old_permission[
'*'];
2548 (array_key_exists(2, $permission)
2549 && $permission[2] >=
'R')
2550 && array_key_exists(2, $old_permission)
2551 && $old_permission[2] >=
'R'
2560 @set_time_limit(300);
2564 while (
false !== ($file = @readdir(
$handle)))
2566 if ($file ==
'.' || $file ==
'..')
2571 $full_file =
$path .
'/' . $file;
2572 if ($full_file ==
'/bitrix')
2587 FROM b_search_content SC
2588 WHERE MODULE_ID='main'
2599 $arNewGroups[$group_id] =
'G' . $group_id;
2614 $DB = CDatabase::GetModuleConnection(
'search');
2615 $index_id = intval($index_id);
2620 if ($group_code <>
'')
2622 $arToInsert[$group_code] = $group_code;
2628 SELECT * FROM b_search_content_right
2629 WHERE SEARCH_CONTENT_ID = ' . $index_id .
'
2631 while (
$ar =
$rs->Fetch())
2633 $group_code =
$ar[
'GROUP_CODE'];
2634 if (isset($arToInsert[$group_code]))
2636 unset($arToInsert[$group_code]);
2641 DELETE FROM b_search_content_right
2643 SEARCH_CONTENT_ID = ' . $index_id .
"
2644 AND GROUP_CODE = '" .
$DB->ForSQL($group_code) .
"'
2649 foreach ($arToInsert as $group_code)
2652 INSERT INTO b_search_content_right
2653 (SEARCH_CONTENT_ID, GROUP_CODE)
2655 (' . $index_id .
", '" .
$DB->ForSQL($group_code, 100) .
"')
2666 if (
$USER->IsAdmin())
2672 if (
$USER->GetID() > 0)
2678 FROM b_search_content_right scg
2679 WHERE ' . $FIELD .
' = scg.SEARCH_CONTENT_ID
2680 AND scg.GROUP_CODE IN (
2681 SELECT GROUP_CODE FROM b_search_user_right
2682 WHERE USER_ID = ' .
$USER->GetID() .
'
2691 FROM b_search_content_right scg
2692 WHERE ' . $FIELD .
" = scg.SEARCH_CONTENT_ID
2693 AND scg.GROUP_CODE = 'G2'
2697 return '((' . implode(
') OR (',
$arResult) .
'))';
2702 $DB = CDatabase::GetModuleConnection(
'search');
2703 $index_id = intval($index_id);
2714 $sql_name =
"'" .
$DB->ForSQL(
$name, 100) .
"'";
2721 foreach ($v1 as $v2)
2726 $sql_value =
"'" .
$DB->ForSQL($value, 100) .
"'";
2727 $key = md5($sql_name) . md5($sql_value);
2729 $arToInsert[
$key] =
'
2730 INSERT INTO b_search_content_param
2731 (SEARCH_CONTENT_ID, PARAM_NAME, PARAM_VALUE)
2733 (' . $index_id .
', ' . $sql_name .
', ' . $sql_value .
')
2741 if (empty($arToInsert))
2744 DELETE FROM b_search_content_param
2746 SEARCH_CONTENT_ID = ' . $index_id .
'
2752 SELECT PARAM_NAME, PARAM_VALUE
2753 FROM b_search_content_param
2754 WHERE SEARCH_CONTENT_ID = ' . $index_id .
'
2756 while (
$ar =
$rs->Fetch())
2758 $sql_name =
"'" .
$DB->ForSQL(
$ar[
'PARAM_NAME'], 100) .
"'";
2759 $sql_value =
"'" .
$DB->ForSQL(
$ar[
'PARAM_VALUE'], 100) .
"'";
2760 $key = md5($sql_name) . md5($sql_value);
2762 if (array_key_exists(
$key, $arToInsert))
2764 unset($arToInsert[
$key]);
2769 DELETE FROM b_search_content_param
2771 SEARCH_CONTENT_ID = ' . $index_id .
'
2772 AND PARAM_NAME = ' . $sql_name .
'
2773 AND PARAM_VALUE = ' . $sql_value .
'
2779 foreach ($arToInsert as $sql)
2787 $DB = CDatabase::GetModuleConnection(
'search');
2788 $index_id = intval($index_id);
2798 SELECT PARAM_NAME, PARAM_VALUE
2799 FROM b_search_content_param
2800 WHERE SEARCH_CONTENT_ID = ' . $index_id .
'
2801 ' . ($param_name && $param_name <>
'' ?
" AND PARAM_NAME = '" .
$DB->ForSQL($param_name) .
"'" :
'') .
'
2803 while (
$ar =
$rs->Fetch())
2821 $variance += pow($v - $mean, 2);
2829 while ($words_count > 0)
2831 $a[] = $words_count--;
2838 $DB = CDatabase::GetModuleConnection(
'search');
2841 if ($MODULE_ID !=
'')
2843 $strFilter .=
" AND MODULE_ID = '" .
$DB->ForSql($MODULE_ID) .
"' ";
2849 $strFilter .=
" AND scsite.SITE_ID = '" .
$DB->ForSql(
$SITE_ID) .
"' ";
2850 $strJoin .=
' INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID ';
2853 if (!is_array($SESS_ID))
2855 $SESS_ID = [$SESS_ID];
2858 foreach ($SESS_ID as
$key => $value)
2860 $SESS_ID[
$key] =
$DB->ForSql($value);
2865 FROM b_search_content sc
2867 WHERE (UPD not in ('" . implode(
"', '", $SESS_ID) .
"') OR UPD IS NULL)
2873 $rs =
$DB->Query($strSql);
2874 while (
$ar =
$rs->Fetch())
2876 foreach ($arEvents as $arEvent)
2881 $DB->Query(
'DELETE FROM b_search_content_param WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2882 $DB->Query(
'DELETE FROM b_search_content_right WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2883 $DB->Query(
'DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2884 $DB->Query(
'DELETE FROM b_search_content_title WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2885 $DB->Query(
'DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2887 $DB->Query(
'DELETE FROM b_search_content WHERE ID = ' .
$ar[
'ID']);
2895 $DB = CDatabase::GetModuleConnection(
'search');
2897 $MODULE_ID =
$DB->ForSql($MODULE_ID);
2898 $strSql =
"SELECT ID FROM b_search_content WHERE MODULE_ID = '" . $MODULE_ID .
"'";
2902 $rs =
$DB->Query($strSql);
2903 while (
$ar =
$rs->Fetch())
2905 foreach ($arEvents as $arEvent)
2910 $DB->Query(
'DELETE FROM b_search_content_param WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2911 $DB->Query(
'DELETE FROM b_search_content_right WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2912 $DB->Query(
'DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2913 $DB->Query(
'DELETE FROM b_search_content_title WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2914 $DB->Query(
'DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2916 $DB->Query(
'DELETE FROM b_search_content WHERE ID = ' .
$ar[
'ID']);
2922 public static function DeleteIndex($MODULE_ID, $ITEM_ID =
false, $PARAM1 =
false, $PARAM2 =
false,
$SITE_ID =
false)
2924 $DB = CDatabase::GetModuleConnection(
'search');
2926 $op = (mb_strpos($ITEM_ID,
'%') !==
false ?
'%=' :
'=');
2928 if ($PARAM1 !==
false && $PARAM2 !==
false)
2931 'MODULE_ID' => $MODULE_ID,
2932 $op .
'ITEM_ID' => $ITEM_ID,
2934 '=PARAM1' => $PARAM1,
2935 'PARAM2' => $PARAM2,
2943 'MODULE_ID' => $MODULE_ID,
2944 $op .
'ITEM_ID' => $ITEM_ID,
2945 'PARAM1' => $PARAM1,
2946 'PARAM2' => $PARAM2,
2953 FROM b_search_content sc
2954 ' . ($bIncSites ?
'INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID' :
'') .
'
2961 $rs =
$DB->Query($strSql);
2962 while (
$ar =
$rs->Fetch())
2964 foreach ($arEvents as $arEvent)
2969 $DB->Query(
'DELETE FROM b_search_content_param WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2970 $DB->Query(
'DELETE FROM b_search_content_right WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2971 $DB->Query(
'DELETE FROM b_search_content_site WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2972 $DB->Query(
'DELETE FROM b_search_content_title WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2973 $DB->Query(
'DELETE FROM b_search_tags WHERE SEARCH_CONTENT_ID = ' .
$ar[
'ID']);
2975 $DB->Query(
'DELETE FROM b_search_content WHERE ID = ' .
$ar[
'ID']);
2983 $DB = CDatabase::GetModuleConnection(
'search');
2986 if (array_key_exists(
'~DATE_CHANGE',
$arFields))
2998 $arFields[
'DATE_CHANGE'] =
$DB->FormatDate(
$arFields[
'DATE_CHANGE'],
'DD.MM.YYYY HH:MI:SS', CLang::GetDateFormat());
3001 if (array_key_exists(
'SITE_ID',
$arFields))
3007 if (array_key_exists(
'PERMISSIONS',
$arFields))
3010 foreach (
$arFields[
'PERMISSIONS'] as $group_id)
3012 if (is_numeric($group_id))
3014 $arNewGroups[$group_id] =
'G' . intval($group_id);
3018 $arNewGroups[$group_id] = $group_id;
3025 if (array_key_exists(
'PARAMS',
$arFields))
3031 $strUpdate =
$DB->PrepareUpdate(
'b_search_content',
$arFields);
3032 if ($strUpdate <>
'')
3034 $DB->Query(
'UPDATE b_search_content SET ' . $strUpdate .
' WHERE ID = ' . intval(
$ID));
3046 $DB = CDatabase::GetModuleConnection(
'search');
3050 'MODULE_ID' => $MODULE_ID,
3051 'ITEM_ID' => $ITEM_ID,
3052 'PARAM1' => $PARAM1,
3053 'PARAM2' => $PARAM2,
3058 FROM b_search_content sc
3059 ' . ($bIncSites ?
'INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID' :
'') .
'
3062 $rs =
$DB->Query($strSql);
3063 while (
$ar =
$rs->Fetch())
3069 public static function ChangeSite($MODULE_ID, $arSite, $ITEM_ID =
false, $PARAM1 =
false, $PARAM2 =
false,
$SITE_ID =
false)
3071 $DB = CDatabase::GetModuleConnection(
'search');
3075 'MODULE_ID' => $MODULE_ID,
3076 'ITEM_ID' => $ITEM_ID,
3077 'PARAM1' => $PARAM1,
3078 'PARAM2' => $PARAM2,
3084 FROM b_search_content sc
3085 ' . ($bIncSites ?
'INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID' :
'') .
'
3090 $r =
$DB->Query($strSql);
3091 while ($arR = $r->Fetch())
3099 $DB = CDatabase::GetModuleConnection(
'search');
3103 'MODULE_ID' => $MODULE_ID,
3104 'ITEM_ID' => $ITEM_ID,
3105 'PARAM1' => $PARAM1,
3106 'PARAM2' => $PARAM2,
3108 'PARAMS' => $PARAMS,
3113 $strSqlJoin1 =
'INNER JOIN b_search_content sc ON sc.ID = b_search_content_right.SEARCH_CONTENT_ID';
3116 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))
3118 $subTable = str_replace(
'SEARCH_CONTENT_ID = sc.ID AND',
'', $match[1]);
3119 $strSqlJoin2 =
'INNER JOIN ' . $subTable .
' p1 ON p1.SEARCH_CONTENT_ID = sc.ID';
3134 FROM b_search_content sc
3135 ' . $strSqlJoin2 .
'
3141 while ($arR =
$rs->fetch())
3162 if (is_array($field_value))
3164 $sql_values = array_map([
$DB,
'ForSQL'], array_filter($field_value));
3166 elseif ($field_value !==
false)
3168 $sql_values = [
$DB->ForSQL($field_value)];
3176 if (!empty($sql_values))
3184 foreach ($sql_values as $url_i)
3186 $arSQL[] = $this->strSearchContentAlias .
".URL LIKE '" . $url_i .
"'";
3187 $arSQL[] =
"scsite.URL LIKE '" . $url_i .
"'";
3189 $strSql =
'(' . implode(
') OR (', $arSQL) .
')';
3190 $this->bIncSites =
true;
3197 foreach ($sql_values as $url_i)
3199 $arSQL[] = $this->strSearchContentAlias .
".URL NOT LIKE '" . $url_i .
"'";
3200 $arSQL[] =
"scsite.URL NOT LIKE '" . $url_i .
"'";
3202 $strSql =
'(' . implode(
') AND (', $arSQL) .
')';
3203 $this->bIncSites =
true;
3212 return '(' . $strSql .
')';
3225 if (is_array($field_value))
3227 foreach ($field_value as
$key =>
$val)
3231 foreach (
$val as
$i => $val2)
3235 $where =
" in ('" . implode(
"', '",
$val) .
"')";
3239 $where =
" = '" .
$DB->ForSQL(
$val) .
"'";
3241 $arSql[] =
'EXISTS (SELECT * FROM b_search_content_param WHERE SEARCH_CONTENT_ID = ' . $field_name .
" AND PARAM_NAME = '" .
$DB->ForSQL(
$key) .
"' AND PARAM_VALUE " . $where .
')';
3253 return implode(
' AND ', $arSql);
3281 $this->m_query =
'';
3282 $this->m_stemmed_words = [];
3283 $this->m_tags_words = [];
3284 $this->m_fields =
'';
3291 $db_site_tmp = CSite::GetByID(
$site_id);
3292 if ($ar_site_tmp = $db_site_tmp->Fetch())
3294 $this->m_lang = $ar_site_tmp[
'LANGUAGE_ID'];
3298 $this->m_lang =
'en';
3304 $this->m_words = [];
3305 $this->m_fields = explode(
',',
$fields);
3311 $this->m_tags_words = [];
3316 $this->bStemming =
false;
3317 if (!$this->bTagsSearch && $bUseStemming && COption::GetOptionString(
'search',
'use_stemming') ==
'Y')
3321 if ($this->bStemming ===
true || $bErrorOnEmptyStem)
3343 if (preg_match_all(
"/([\"'])(.*?)(?<!\\\\)(\\1)/s",
$query, $arQuotes))
3345 foreach ($arQuotes[2] as
$i => $quoted)
3347 $quoted = trim($quoted);
3350 $repl =
$i .
'cut5';
3351 $this->m_kav[$repl] = str_replace(
'\\"',
'"', $quoted);
3352 $query = str_replace($arQuotes[0][
$i],
' ' . $repl .
' ',
$query);
3379 [
'&',
'|',
'~',
'(',
')'],
3380 [
' && ',
' || ',
' ! ',
' ( ',
' ) '],
3383 $q =
'( ' . $q .
' )';
3384 $q = preg_replace(
'/\\s+/u',
' ', $q);
3393 $letters = $arStemInfo[
'pcre_letters'] .
'|+&~()';
3396 $qwe = trim(preg_replace(
'/[^' . $letters .
']+/u',
' ', $qwe));
3399 if (!$this->no_bool_lang)
3401 $qwe = preg_replace(
'/(\\s+|^|[|&~])or(\\s+|$|[|&~])/isu',
"\\1|\\2", $qwe);
3402 $qwe = preg_replace(
'/(\\s+|^|[|&~])and(\\s+|$|[|&~])/isu',
"\\1&\\2", $qwe);
3403 $qwe = preg_replace(
'/(\\s+|^|[|&~])not(\\s+|$|[|&~])/isu',
"\\1~\\2", $qwe);
3404 $qwe = preg_replace(
'/(\\s+|^|[|&~])without(\\s+|$|[|&~])/isu',
"\\1~\\2", $qwe);
3406 if ($this->rus_bool_lang ==
'yes')
3408 $qwe = preg_replace(
'/(\\s+|^|[|&~])' .
GetMessage(
'SEARCH_TERM_OR') .
'(\\s+|$|[|&~])/isu',
"\\1|\\2", $qwe);
3409 $qwe = preg_replace(
'/(\\s+|^|[|&~])' .
GetMessage(
'SEARCH_TERM_AND') .
'(\\s+|$|[|&~])/isu',
"\\1&\\2", $qwe);
3410 $qwe = preg_replace(
'/(\\s+|^|[|&~])' .
GetMessage(
'SEARCH_TERM_NOT_1') .
'(\\s+|$|[|&~])/isu',
"\\1~\\2", $qwe);
3411 $qwe = preg_replace(
'/(\\s+|^|[|&~])' .
GetMessage(
'SEARCH_TERM_NOT_2') .
'(\\s+|$|[|&~])/isu',
"\\1~\\2", $qwe);
3415 $qwe = preg_replace(
'/(\\s*\\|+\\s*)/isu',
'|', $qwe);
3416 $qwe = preg_replace(
'/(\\s*\\++\\s*|\\s*\\&\\s*)/isu',
'&', $qwe);
3417 $qwe = preg_replace(
'/(\\s*\\~+\\s*)/isu',
'~', $qwe);
3419 $qwe = preg_replace(
'/\s*([()])\s*/su',
"\\1", $qwe);
3422 if (mb_strtolower($this->default_query_type) ==
'or')
3431 $qwe = preg_replace(
'/(\s+|\&\|+|\|\&+)/su', $default_op, $qwe);
3434 $qwe = preg_replace(
'/\|+/',
'|', $qwe);
3435 $qwe = preg_replace(
'/&+/',
'&', $qwe);
3436 $qwe = preg_replace(
'/~+/',
'~', $qwe);
3437 $qwe = preg_replace(
'/\|\&\|/',
'&', $qwe);
3438 $qwe = preg_replace(
'/[\|\&\~]+$/',
'', $qwe);
3439 $qwe = preg_replace(
'/^[\|\&]+/',
'', $qwe);
3448 $qwe = preg_replace(
'/([^\&\~\|\(\)]+)~([^\&\~\|\(\)]+)/su',
"\\1" . $default_op .
"~\\2", $qwe);
3449 $qwe = preg_replace(
'/\)~{1,}/su',
')' . $default_op .
'~', $qwe);
3450 $qwe = preg_replace(
'/~{1,}\(/su', ($default_op ==
'|' ?
'~|(' :
'&~('), $qwe);
3451 $qwe = preg_replace(
'/\)([^\&\~\|\(\)]+)/su',
')' . $default_op .
"\\1", $qwe);
3452 $qwe = preg_replace(
'/([^\&\~\|\(\)]+)\(/su',
"\\1" . $default_op .
'(', $qwe);
3453 $qwe = preg_replace(
'/\) *\(/su',
')' . $default_op .
'(', $qwe);
3456 $qwe = preg_replace(
'/\|+/',
'|', $qwe);
3457 $qwe = preg_replace(
'/&+/',
'&', $qwe);
3460 $qwe = preg_replace(
'/\(\&{1,}/s',
'(', $qwe);
3461 $qwe = preg_replace(
'/\&{1,}\)/s',
')', $qwe);
3462 $qwe = preg_replace(
'/\~{1,}\)/s',
')', $qwe);
3463 $qwe = preg_replace(
'/\(\|{1,}/s',
'(', $qwe);
3464 $qwe = preg_replace(
'/\|{1,}\)/s',
')', $qwe);
3465 $qwe = preg_replace(
'/\~{1,}\&{1,}/s',
'&', $qwe);
3466 $qwe = preg_replace(
'/\~{1,}\|{1,}/s',
'|', $qwe);
3468 $qwe = preg_replace(
'/\(\)/s',
'', $qwe);
3469 $qwe = preg_replace(
'/^[\|\&]{1,}/s',
'', $qwe);
3470 $qwe = preg_replace(
'/[\|\&\~]{1,}$/s',
'', $qwe);
3471 $qwe = preg_replace(
'/\|\&/s',
'&', $qwe);
3472 $qwe = preg_replace(
'/\&\|/s',
'|', $qwe);
3475 $qwe = preg_replace(
'/\|+/',
'|', $qwe);
3476 $qwe = preg_replace(
'/&+/',
'&', $qwe);
3483 static $preg_ru =
false;
3488 $wu = mb_strtoupper($w);
3490 if (!$this->no_bool_lang)
3492 if (preg_match(
'/^(OR|AND|NOT|WITHOUT)$/', $wu))
3496 elseif ($this->rus_bool_lang ==
'yes')
3498 if ($preg_ru ===
false)
3502 if (preg_match($preg_ru, $wu))
3509 if (preg_match(
'/cut[56]/i', $w))
3513 $arrStem = array_keys(
stemming($w, $this->m_lang));
3514 if (
count($arrStem) < 1)
3520 $this->bStemming =
true;
3521 return '(' . implode(
'|', $arrStem) .
')';
3528 return preg_replace_callback(
'/([' . $arStemInfo[
'pcre_letters'] .
']+)/u', [$this,
'StemWord'], $q);
3538 foreach (preg_split(
'/ +/', $q) as $t)
3542 if (($t ===
'||') || ($t ===
'&&') || ($t ===
')'))
3544 $this->error =
GetMessage(
'SEARCH_ERROR2') .
' ' . $t;
3562 $where = $this->BuildWhereClause($t);
3567 ($c > 0 && $qu[$c - 1] ===
' OR ')
3568 || ($c > 1 && $qu[$c - 1] ===
'(' && $qu[$c - 2] ===
' OR ')
3574 $qu[] =
' ' . $where .
' ';
3579 if (($t ===
'||') || ($t ===
'&&'))
3599 $this->error =
GetMessage(
'SEARCH_ERROR2') .
' ' . $t;
3606 if (($this->error ===
'') && (
$n !== 0))
3612 if ($this->error !=
'')
3617 return implode($qu);
3637 $this->CNT = $this->CNT + 1;
3638 if ($this->max_execution_time > 0 && microtime(
true) -
START_EXEC_TIME > $this->max_execution_time)
static convertEncoding($data, $charsetFrom, $charsetTo)
static DeleteByTag($tagId)
static GetList($by='c_sort', $order='asc', $arFilter=[], $SHOW_USERS_AMOUNT="N")
static ChangeIndex($MODULE_ID, $arFields, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $SITE_ID=false)
static OnChangeFile($path, $site)
static ChangePermission($MODULE_ID, $arGroups, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $SITE_ID=false, $PARAMS=false)
Repl($strCond, $strType, $strWh)
static RecurseIndex($path=[], $max_execution_time=0, &$NS)
static __PrepareFilter($arFilter, &$bIncSites, $strSearchContentAlias='sc.')
$_opt_ERROR_ON_EMPTY_STEM
GetFreqStatistics($lang_id, $arStem, $site_id='')
static KillEntities($str)
static DeleteIndex($MODULE_ID, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $SITE_ID=false)
static GetContentItemParams($index_id, $param_name=false)
static DeleteOld($SESS_ID, $MODULE_ID='', $SITE_ID='')
static ReindexModule($MODULE_ID, $bFull=false)
static ChangeSite($MODULE_ID, $arSite, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $SITE_ID=false)
CSearch($strQuery=false, $LID=false, $MODULE_ID=false, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $aSort=[], $aParamsEx=[], $bTagsCloud=false)
static CheckPermissions($FIELD='sc.ID')
static ReindexFile($path, $SEARCH_SESS_ID='')
static QueryMnogoSearch(&$xml)
static DeleteForReindex($MODULE_ID)
NavStart($nPageSize=0, $bShowAll=true, $iNumPage=false)
static ReIndexAll($bFull=false, $max_execution_time=0, $NS=[], $clear_suggest=false)
Search($arParams, $aSort=[], $aParamsEx=[], $bTagsCloud=false)
__construct($strQuery=false, $SITE_ID=false, $MODULE_ID=false, $ITEM_ID=false, $PARAM1=false, $PARAM2=false, $aSort=[], $aParamsEx=[], $bTagsCloud=false)
static OnGroupDelete($ID)
static GetIndex($MODULE_ID, $ITEM_ID)
PrepareSearchResult($str)
static OnChangeFilePermissions($path, $permission=[], $old_permission=[], $arGroups=false)
__PrepareSort($aSort=[], $strSearchContentAlias='sc.', $bTagsCloud=false)
static Update($ID, $arFields)
static SetContentItemParams($index_id, $arParams)
static Index($MODULE_ID, $ITEM_ID, $arFields, $bOverWrite=false, $SEARCH_SESS_ID='')
static SetContentItemGroups($index_id, $arGroups)
__construct($default_query_type='and', $rus_bool_lang='yes', $m_casematch=0, $site_id='')
GetQueryString($fields, $query, $bTagsSearch=false, $bUseStemming=true, $bErrorOnEmptyStem=false)
StemQuery($q, $lang='en')
static CleanFreqCache($ID)
static TagsIndex($arLID, $ID, $sContent)
static IndexTitle($arLID, $ID, $sTitle)
static UpdateSite($ID, $arSITE_ID)
_CallbackURL($field_name, $operation, $field_value)
_CallbackPARAMS($field_name, $operation, $field_value)
__construct($strSearchContentAlias)
static CheckCurrentUserGroups()
if(!defined('SITE_ID')) $lang
if(!defined('NOT_CHECK_PERMISSIONS')) $NS
ExecuteModuleEventEx($arEvent, $arParams=[])
ParseFileContent($filesrc, $params=[])
FormatDate($format="", $timestamp=false, $now=false, ?string $languageId=null)
GetModuleEvents($MODULE_ID, $MESSAGE_ID, $bReturnArray=false)
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
GetMessage($name, $aReplace=null)
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
if(empty($signedUserToken)) $key
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
stemming_init($sLang='ru')
stemming_upper($sText, $sLang='ru')
stemming($sText, $sLang='ru', $bIgnoreStopWords=false, $bReturnPositions=false)