8 private static $fields = [
11 'module_id' =>
'uint',
15 'param1_id' =>
'uint',
17 'param2_id' =>
'uint',
19 'date_change' =>
'timestamp',
20 'date_from' =>
'timestamp',
21 'date_to' =>
'timestamp',
22 'custom_rank' =>
'uint',
28 private static $typesMap = [
29 'timestamp' =>
'rt_attr_timestamp',
30 'string' =>
'rt_attr_string',
31 'bigint' =>
'rt_attr_bigint',
32 'uint' =>
'rt_attr_uint',
33 'field' =>
'rt_field',
34 'mva' =>
'rt_attr_multi',
36 private $errorText =
'';
37 private $errorNumber = 0;
48 if (!preg_match(
'/^[a-zA-Z0-9_]+$/',
$indexName))
56 throw new \Bitrix\Main\Db\ConnectionException(
'Sphinx connect error',
GetMessage(
'SEARCH_SPHINX_CONN_ERROR_INDEX_NAME'));
69 throw new \Bitrix\Main\Db\ConnectionException(
'Sphinx connect error',
GetMessage(
'SEARCH_SPHINX_CONN_EXT_IS_MISSING'));
84 throw new \Bitrix\Main\Db\ConnectionException(
'Sphinx connect error',
GetMessage(
'SEARCH_SPHINX_CONN_ERROR', [
'#ERRSTR#' =>
$error]));
109 $indexType =
$res[
'Type'];
113 if ($indexType ==
'')
119 if ($indexType !=
'rt')
135 $indexColumns[
$res[
'Field']] =
$res[
'Type'];
143 $missed[] = self::$typesMap[
$type] .
' = ' .
$name;
149 $APPLICATION->ThrowException(
GetMessage(
'SEARCH_SPHINX_NO_FIELDS', [
'#FIELD_LIST#' => implode(
', ', $missed)]));
162 $this->
query(
'truncate rtindex ' . $this->indexName);
163 $this->
connect($this->connectionIndex, $this->indexName);
168 $this->
query(
'delete from ' . $this->indexName .
' where id = ' . intval(
$ID));
173 $DB = CDatabase::GetModuleConnection(
'search');
175 if (array_key_exists(
'~DATE_CHANGE',
$arFields))
187 $arFields[
'DATE_CHANGE'] =
$DB->FormatDate(
$arFields[
'DATE_CHANGE'],
'DD.MM.YYYY HH:MI:SS', CLang::GetDateFormat());
193 $DATE_FROM -= CTimeZone::GetOffset();
198 $DATE_TO -= CTimeZone::GetOffset();
201 if ($DATE_CHANGE > 0)
203 $DATE_CHANGE -= CTimeZone::GetOffset();
209 REPLACE INTO ' . $this->indexName .
' (
231 ,' . sprintf(
'%u', crc32(
$arFields[
'MODULE_ID'])) .
"
233 ," . sprintf(
'%u', crc32(
$arFields[
'ITEM_ID'])) .
"
235 ," . sprintf(
'%u', crc32(
$arFields[
'PARAM1'])) .
"
237 ," . sprintf(
'%u', crc32(
$arFields[
'PARAM2'])) .
"
239 ," . $DATE_CHANGE .
'
242 ,' . intval(
$arFields[
'CUSTOM_RANK']) .
'
248 ,'" . $this->
Escape($BODY) .
"'
258 throw new \Bitrix\Main\Db\SqlQueryException(
'Sphinx select error', $this->
getError(), $sql);
264 $DB = CDatabase::GetModuleConnection(
'search');
268 $bReplace = array_key_exists(
'TITLE',
$arFields)
270 || array_key_exists(
'MODULE_ID',
$arFields)
271 || array_key_exists(
'ITEM_ID',
$arFields)
276 if (array_key_exists(
'~DATE_CHANGE',
$arFields))
288 $arFields[
'DATE_CHANGE'] =
$DB->FormatDate(
$arFields[
'DATE_CHANGE'],
'DD.MM.YYYY HH:MI:SS', CLang::GetDateFormat());
291 if (array_key_exists(
'DATE_CHANGE',
$arFields))
294 if ($DATE_CHANGE > 0)
296 $DATE_CHANGE -= CTimeZone::GetOffset();
298 $arUpdate[
'date_change'] = $DATE_CHANGE;
301 if (array_key_exists(
'DATE_FROM',
$arFields))
306 $DATE_FROM -= CTimeZone::GetOffset();
308 $arUpdate[
'date_from'] = $DATE_FROM;
311 if (array_key_exists(
'DATE_TO',
$arFields))
316 $DATE_TO -= CTimeZone::GetOffset();
318 $arUpdate[
'date_to'] = $DATE_TO;
321 if (array_key_exists(
'CUSTOM_RANK',
$arFields))
323 $arUpdate[
'custom_rank'] =
'' . intval(
$arFields[
'CUSTOM_RANK']) .
'';
331 if (array_key_exists(
'PERMISSIONS',
$arFields))
333 $arUpdate[
'right'] =
'(' . $this->
rights(
$arFields[
'PERMISSIONS']) .
')';
336 if (array_key_exists(
'SITE_ID',
$arFields))
338 $arUpdate[
'site'] =
'(' . $this->
sites(
$arFields[
'SITE_ID']) .
')';
341 if (array_key_exists(
'PARAMS',
$arFields))
346 if (!empty($arUpdate) && !$bReplace)
348 foreach ($arUpdate as $columnName => $sqlValue)
350 $arUpdate[$columnName] = $columnName .
'=' . $sqlValue;
354 UPDATE ' . $this->indexName .
' SET
355 ' . implode(
', ', $arUpdate) .
'
361 $dbItem =
$DB->Query(
'
364 ,' .
$DB->DateToCharFunction(
'DATE_CHANGE') .
' as LAST_MODIFIED
365 ,' .
$DB->DateToCharFunction(
'DATE_FROM') .
' as DATE_FROM
366 ,' .
$DB->DateToCharFunction(
'DATE_TO') .
' as DATE_TO
367 FROM b_search_content
370 $searchItem = $dbItem->fetch();
373 $dbTags =
$DB->Query(
'SELECT * from b_search_tags WHERE SEARCH_CONTENT_ID=' .
$ID);
374 while ($tag = $dbTags->fetch())
376 $searchItem[
'TAGS'] .= $tag[
'NAME'] .
',';
379 $dbRights =
$DB->Query(
'SELECT * from b_search_content_right WHERE SEARCH_CONTENT_ID=' .
$ID);
380 while (
$right = $dbRights->fetch())
382 $searchItem[
'PERMISSIONS'][] =
$right[
'GROUP_CODE'];
385 $dbSites =
$DB->Query(
'SELECT * from b_search_content_site WHERE SEARCH_CONTENT_ID=' .
$ID);
388 $searchItem[
'SITE_ID'][
$site[
'SITE_ID']] =
$site[
'URL'];
391 $dbParams =
$DB->Query(
'SELECT * from b_search_content_param WHERE SEARCH_CONTENT_ID=' .
$ID);
392 while ($param = $dbParams->fetch())
394 $searchItem[
'PARAMS'][$param[
'PARAM_NAME']][] = $param[
'PARAM_VALUE'];
402 function tags($arLID, $sContent)
405 if (is_array($arLID))
410 foreach ($arTags as $tag)
412 $tags[] = sprintf(
'%u', crc32($tag));
416 return implode(
',',
$tags);
421 $DB = CDatabase::GetModuleConnection(
'search');
424 if (is_array($arLID))
429 foreach ($arTags as $tag)
431 $tag_id = sprintf(
'%u', crc32($tag));
432 if ($tag_id > 0x7FFFFFFF)
434 $tag_id = -(0xFFFFFFFF - $tag_id + 1);
437 if (!isset($tagMap[$tag_id]))
439 $rs =
$DB->Query(
'select * from b_search_tags where SEARCH_CONTENT_ID=' . $tag_id .
" AND SITE_ID='??'");
440 $tagMap[$tag_id] =
$rs->fetch();
441 if (!$tagMap[$tag_id])
443 $DB->Query(
'insert into b_search_tags values (' . $tag_id .
", '??', '" .
$DB->ForSql($tag) .
"')");
454 if (is_array($arTags))
456 foreach ($arTags as $tag)
458 $tags[] = sprintf(
'%u', crc32($tag));
461 return implode(
',',
$tags);
467 if (is_array($arRights))
469 foreach ($arRights as $group_id)
471 if (is_numeric($group_id))
473 $rights[$group_id] = sprintf(
'%u', crc32(
'G' . intval($group_id)));
477 $rights[$group_id] = sprintf(
'%u', crc32($group_id));
498 return implode(
',',
$sites);
521 $params[] = sprintf(
'%u', crc32(urlencode(
$name) .
'=' . urlencode($value)));
532 return $this->errorText;
537 return $this->errorNumber;
543 $this->errorText =
'';
544 $this->errorNumber = 0;
549 if (is_array($aParamsEx) && isset($aParamsEx[
'LIMIT']))
551 $limit = intval($aParamsEx[
'LIMIT']);
552 unset($aParamsEx[
'LIMIT']);
556 if (is_array($aParamsEx) && isset($aParamsEx[
'OFFSET']))
558 $offset = intval($aParamsEx[
'OFFSET']);
559 unset($aParamsEx[
'OFFSET']);
562 if (is_array($aParamsEx) && !empty($aParamsEx))
564 $aParamsEx[
'LOGIC'] =
'OR';
576 $arWhere[] =
'right in (' .
$rights .
')';
582 $arWhere[] =
"MATCH('" . $this->
Escape($strQuery) .
"')";
583 $this->
query = $strQuery;
588 $arWhere[] =
'cond1 = 1';
591 if ($strQuery || $this->
tags || $bTagsCloud)
595 $limit = intval(COption::GetOptionInt(
'search',
'max_result_size'));
603 $ts = time() - CTimeZone::GetOffset();
607 select groupby() tag_id
609 ,max(date_change) dc_tmp
610 ,if(date_to, date_to, ' . $ts .
') date_to_nvl
611 ,if(date_from, date_from, ' . $ts .
') date_from_nvl
612 ' . ($cond1 !=
'' ?
',' . $cond1 .
' as cond1' :
'') .
'
613 from ' . $this->indexName .
'
614 where ' . implode(
"\nand\t", $arWhere) .
'
617 limit 0, ' . $limit .
'
618 option max_matches = ' . $limit .
'
621 $DB = CDatabase::GetModuleConnection(
'search');
624 $r = $this->
query($sql);
626 if (
$DB->ShowSqlStat)
633 throw new \Bitrix\Main\Db\SqlQueryException(
'Sphinx select error', $this->
getError(), $sql);
655 ' . ($cond1 !=
'' ?
',' . $cond1 .
' as cond1' :
'') .
'
656 ,if(date_to, date_to, ' . $ts .
') date_to_nvl
657 ,if(date_from, date_from, ' . $ts .
') date_from_nvl
658 from ' . $this->indexName .
'
659 where ' . implode(
"\nand\t", $arWhere) .
'
661 limit ' . $offset .
', ' . $limit .
'
662 option max_matches = ' . ($offset + $limit) .
'
665 $DB = CDatabase::GetModuleConnection(
'search');
668 $r = $this->
query($sql);
670 if (
$DB->ShowSqlStat)
677 throw new \Bitrix\Main\Db\SqlQueryException(
'Sphinx select error', $this->
getError(), $sql);
681 $forum = sprintf(
'%u', crc32(
'forum'));
684 if (
$res[
'module_id'] == $forum)
686 if (array_key_exists(
$res[
'param2_id'], $this->arForumTopics))
690 $this->arForumTopics[
$res[
'param2_id']] =
true;
699 $this->errorText =
GetMessage(
'SEARCH_ERROR3');
700 $this->errorNumber = 3;
709 foreach (array_reverse(
$arPhrase,
true) as $word => $pos)
711 $word = $this->
Escape($word);
712 if (empty($sqlWords) && !preg_match(
"/[\\n\\r \\t]$/", $phrase))
714 $sqlWords[] = $word .
'*';
721 $match =
'@title ' . implode(
' ', array_reverse($sqlWords));
724 if (array_key_exists(
'CHECK_DATES',
$arParams))
736 if (isset($arWhere[
'cond1']))
738 $cond1 = $arWhere[
'cond1'];
739 unset($arWhere[
'cond1']);
742 $ts = time() - CTimeZone::GetOffset();
745 $arWhere[] =
'date_from_nvl <= ' . $ts;
746 $arWhere[] =
'date_to_nvl >= ' . $ts;
752 $arWhere[] =
'right in (' .
$rights .
')';
755 $arWhere[] =
'site = ' . sprintf(
'%u', crc32(
SITE_ID));
756 $arWhere[] =
"match('" . $match .
"')";
761 ' . ($cond1 !=
'' ?
',' . $cond1 .
' as cond1' :
'') .
'
762 ,if(date_to, date_to, ' . $ts .
') date_to_nvl
763 ,if(date_from, date_from, ' . $ts .
') date_from_nvl
764 from ' . $this->indexName .
'
765 where ' . implode(
"\nand\t", $arWhere) .
'
766 ' . ($cond1 !=
'' ?
' and cond1 = ' . intval(!$bNotFilter) :
'') .
'
768 limit 0, ' . $nTopCount .
'
769 option max_matches = ' . $nTopCount .
'
772 $DB = CDatabase::GetModuleConnection(
'search');
775 $r = $this->
query($sql);
777 if (
$DB->ShowSqlStat)
784 throw new \Bitrix\Main\Db\SqlQueryException(
'Sphinx select error', $this->
getError(), $sql);
805 if (is_array($value))
812 foreach ($value as
$i => $v)
814 $s .=
',' . sprintf(
'%u', crc32($v));
816 $arWhere[] =
'in(' . $field .
' ' . $s .
')';
820 foreach ($value as
$i => $v)
822 $s .= ($s ?
' or ' :
'') . $field .
' = ' . sprintf(
'%u', crc32($v));
824 $arWhere[] =
'(' . $s .
')';
830 if ($value !==
false)
832 $arWhere[] = $field .
' = ' . sprintf(
'%u', crc32($value));
847 if (array_key_exists(
'LOGIC',
$arFilter))
855 $field = mb_strtoupper($field);
860 && $field !==
'PARAMS'
861 && !is_numeric($field)
871 $arWhere = array_merge($arWhere, $this->
filterField(
'item_id',
$val, $inSelect));
876 $arWhere[] =
'item_id <> ' . sprintf(
'%u', crc32(
$val));
881 if (
$val !==
false &&
$val !==
'no')
883 $arWhere[] =
'module_id = ' . sprintf(
'%u', crc32(
$val));
888 $arWhere = array_merge($arWhere, $this->
filterField(
'param1_id',
$val, $inSelect));
894 $arWhere[] =
'param1_id <> ' . sprintf(
'%u', crc32(
$val));
899 $arWhere = array_merge($arWhere, $this->
filterField(
'param2_id',
$val, $inSelect));
905 $arWhere[] =
'param2_id <> ' . sprintf(
'%u', crc32(
$val));
911 $arWhere[] =
'date_change >= ' . intval(
MakeTimeStamp(
$val) - CTimeZone::GetOffset());
914 case '<=DATE_CHANGE':
917 $arWhere[] =
'date_change <= ' . intval(
MakeTimeStamp(
$val) - CTimeZone::GetOffset());
920 case '>=DATE_CHANGE':
923 $arWhere[] =
'date_change >= ' . intval(
MakeTimeStamp(
$val) - CTimeZone::GetOffset());
931 $arWhere[] =
'in(site, ' . sprintf(
'%u', crc32(
$val)) .
')';
935 $arWhere[] =
'site = ' . sprintf(
'%u', crc32(
$val));
942 $ts = time() - CTimeZone::GetOffset();
945 $arWhere[] =
'if(date_from, date_from, ' . $ts .
') <= ' . $ts;
946 $arWhere[] =
'if(date_to, date_to, ' . $ts .
') >= ' . $ts;
950 $arWhere[] =
'date_from_nvl <= ' . $ts;
951 $arWhere[] =
'date_to_nvl >= ' . $ts;
956 $arTags = explode(
',',
$val);
957 foreach ($arTags as
$i => &$strTag)
959 $strTag = trim($strTag,
" \n\r\t\"");
967 $arWhere = array_merge($arWhere, $this->
filterField(
'tags', $arTags, $inSelect));
977 $arWhere[] =
'in(param, ' .
$params .
')';
981 foreach (explode(
',',
$params) as $param)
983 $arWhere[] =
'param = ' . $param;
992 case 'USE_TF_FILTER':
995 if (is_numeric($field) && is_array(
$val))
998 if (!empty($subFilter))
1000 if (isset($subFilter[
'cond1']))
1002 $arWhere[
'cond1'][] =
'(' . implode(
')and(', $subFilter) .
')';
1006 $arWhere[] =
'(' . implode(
')and(', $subFilter) .
')';
1018 if (isset($arWhere[
'cond1']))
1020 $arWhere[
'cond1'] =
'(' . implode(
')and(', $arWhere[
'cond1']) .
')';
1023 if ($orLogic && !empty($arWhere))
1026 'cond1' =>
'(' . implode(
')or(', $arWhere) .
')'
1036 $DB = CDatabase::GetModuleConnection(
'search');
1040 if (!
$USER->IsAdmin())
1042 if (
$USER->GetID() > 0)
1045 $rs =
$DB->Query(
'SELECT GROUP_CODE FROM b_search_user_right WHERE USER_ID = ' .
$USER->GetID());
1046 while (
$ar =
$rs->Fetch())
1063 if (!is_array($aSort))
1065 $aSort = [$aSort =>
'ASC'];
1068 $this->flagsUseRatingSort = 0;
1069 foreach ($aSort as
$key => $ord)
1071 $ord = mb_strtoupper($ord) <>
'ASC' ?
'DESC' :
'ASC';
1082 $arOrder[] =
$key .
' ' . $ord;
1085 $arOrder[] =
'item ' . $ord;
1088 $arOrder[] =
'module ' . $ord;
1091 $arOrder[] =
'rank ' . $ord;
1096 if (
count($arOrder) == 0)
1098 $arOrder[] =
'custom_rank DESC';
1099 $arOrder[] =
'rank DESC';
1100 $arOrder[] =
'date_change DESC';
1103 return ' ORDER BY ' . implode(
', ',$arOrder);
1143 $str = str_replace($search, $replace,
$str);
1145 $stat = count_chars(
$str, 1);
1146 if (isset($stat[ord(
'"')]) && $stat[ord(
'"')] % 2 === 1)
1148 $str = str_replace(
'"',
'\\\"',
$str);
1168 return str_replace($search, $replace,
$str);
1173 return function_exists(
'mysqli_connect');
1179 if (function_exists(
'mysqli_connect'))
1186 $port = intval($port);
1198 $error = mysqli_connect_error();
1206 $error = mysqli_connect_error();
1214 $error =
'No MySql connection function has been found.';
1222 if (is_object($this->db))
1235 if (is_object($this->db))
1237 $result = mysqli_fetch_assoc($queryResult);
1248 if (is_object($this->db))
1250 $result =
'[' . $this->db->errno .
'] ' . $this->db->error;
1263 private $sphinx =
null;
1267 $this->sphinx = $sphinx;
1274 if (array_key_exists(
'tag_id', $r))
1278 elseif (array_key_exists(
'id', $r))
1287 $DB = CDatabase::GetModuleConnection(
'search');
1289 $tag_id = $r[
'tag_id'];
1290 if ($tag_id > 0x7FFFFFFF)
1292 $tag_id = -(0xFFFFFFFF - $tag_id + 1);
1298 from b_search_tags st
1299 where st.SEARCH_CONTENT_ID = ' . $tag_id .
"
1300 and st.SITE_ID = '??'
1306 $rt[
'NAME'] = htmlspecialcharsex($rt[
'NAME']);
1307 $rt[
'CNT'] = $r[
'cnt'];
1308 $rt[
'FULL_DATE_CHANGE'] = ConvertTimeStamp($r[
'dc_tmp'] + CTimeZone::GetOffset(),
'FULL');
1309 $rt[
'DATE_CHANGE'] = ConvertTimeStamp($r[
'dc_tmp'] + CTimeZone::GetOffset(),
'SHORT');
1316 $DB = CDatabase::GetModuleConnection(
'search');
1317 if ($this->sphinx->SITE_ID)
1334 ,' .
$DB->DateToCharFunction(
'sc.DATE_CHANGE') .
' as FULL_DATE_CHANGE
1335 ,' .
$DB->DateToCharFunction(
'sc.DATE_CHANGE',
'SHORT') .
' as DATE_CHANGE
1337 ,scsite.URL SITE_URL
1339 from b_search_content sc
1340 INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID
1341 where ID = ' . $r[
'id'] .
"
1342 and scsite.SITE_ID = '" .
$DB->ForSql($this->sphinx->SITE_ID) .
"'
1362 ,' .
$DB->DateToCharFunction(
'sc.DATE_CHANGE') .
' as FULL_DATE_CHANGE
1363 ,' .
$DB->DateToCharFunction(
'sc.DATE_CHANGE',
'SHORT') .
' as DATE_CHANGE
1365 from b_search_content sc
1366 where ID = ' . $r[
'id'] .
'
1372 $r[
'TITLE_FORMATED'] = $this->
buildExcerpts(htmlspecialcharsex($r[
'TITLE']));
1373 $r[
'TITLE_FORMATED_TYPE'] =
'html';
1375 $r[
'BODY_FORMATED'] = $this->
buildExcerpts(htmlspecialcharsex($r[
'BODY']));
1376 $r[
'BODY_FORMATED_TYPE'] =
'html';
1383 $sql =
"CALL SNIPPETS(
1384 '" . $this->sphinx->Escape2(
$str) .
"'
1385 ,'" . $this->sphinx->Escape($this->sphinx->indexName) .
"'
1386 ,'" . $this->sphinx->Escape($this->sphinx->query .
' ' . $this->sphinx->tags) .
"'
1390 $result = $this->sphinx->query($sql);
1397 return $res[
'snippet'];
1406 throw new \Bitrix\Main\Db\SqlQueryException(
'Sphinx select error', $this->sphinx->getError(), $sql);
static KillEntities($str)
searchTitle($phrase='', $arPhrase=[], $nTopCount=5, $arParams=[], $bNotFilter=false, $order='')
internalConnect($connectionIndex, &$error)
prepareFilter($arFilter, $inSelect=false)
connect($connectionIndex, $indexName='', $ignoreErrors=false)
tagsRegister($arLID, $sContent)
filterField($field, $value, $inSelect)
search($arParams, $aSort, $aParamsEx, $bTagsCloud)
static CheckCurrentUserGroups()
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
GetMessage($name, $aReplace=null)
MakeTimeStamp($datetime, $format=false)
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."%"
if($inWords) echo htmlspecialcharsbx(Number2Word_Rus(roundEx($totalVatSum $params['CURRENCY']