1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
title.php
См. документацию.
1<?php
2
3class CSearchTitle extends CDBResult
4{
5 var $_arPhrase = [];
7 var $minLength = 1;
8
9 function __construct($res = null)
10 {
11 $this->_arStemFunc = stemming_init(LANGUAGE_ID);
12 parent::__construct($res);
13 }
14
15 function Search($phrase = '', $nTopCount = 5, $arParams = [], $bNotFilter = false, $order = '')
16 {
17 $DB = CDatabase::GetModuleConnection('search');
18 $this->_arPhrase = stemming_split($phrase, LANGUAGE_ID);
19 if (!empty($this->_arPhrase))
20 {
21 $nTopCount = intval($nTopCount);
22 if ($nTopCount <= 0)
23 {
24 $nTopCount = 5;
25 }
26
27 $arId = CSearchFullText::getInstance()->searchTitle($phrase, $this->_arPhrase, $nTopCount, $arParams, $bNotFilter, $order);
28 if (!is_array($arId))
29 {
30 return $this->searchTitle($phrase, $nTopCount, $arParams, $bNotFilter, $order);
31 }
32 elseif (!empty($arId))
33 {
34 $strSql = '
35 SELECT
36 sc.ID
37 ,sc.MODULE_ID
38 ,sc.ITEM_ID
39 ,sc.TITLE
40 ,sc.PARAM1
41 ,sc.PARAM2
42 ,sc.DATE_CHANGE
43 ,sc.URL as URL
44 ,scsite.URL as SITE_URL
45 ,scsite.SITE_ID
46 ,case when position(\'' . $DB->ForSQL(mb_strtoupper($phrase)) . '\' in upper(sc.TITLE)) > 0 then 1 else 0 end RANK1
47 ,position(\'' . $DB->ForSQL(mb_strtoupper($phrase)) . '\' in upper(sc.TITLE)) RANK2
48 FROM
49 b_search_content sc
50 INNER JOIN b_search_content_site scsite ON sc.ID = scsite.SEARCH_CONTENT_ID
51 WHERE
52 sc.ID in (' . implode(',', $arId) . ")
53 and scsite.SITE_ID = '" . SITE_ID . "'
54 ORDER BY " . (
55 $order == 'rank' ?
56 'RANK1 DESC, RANK2, TITLE' :
57 'DATE_CHANGE DESC, RANK1 DESC, RANK2, TITLE' ) . '
58 ';
59
60 $r = $DB->Query($DB->TopSql($strSql, $nTopCount + 1));
61 parent::__construct($r);
62 return true;
63 }
64 }
65 else
66 {
67 return false;
68 }
69 }
70
71 function setMinWordLength($minLength)
72 {
73 $minLength = intval($minLength);
74 if ($minLength > 0)
75 {
76 $this->minLength = $minLength;
77 }
78 }
79
80 function Fetch()
81 {
82 static $arSite = [];
83
84 $r = parent::Fetch();
85
86 if ($r)
87 {
88 $site_id = $r['SITE_ID'];
89 if (!isset($arSite[$site_id]))
90 {
91 $rsSite = CSite::GetList('', '', ['ID' => $site_id]);
92 $arSite[$site_id] = $rsSite->Fetch();
93 }
94 $r['DIR'] = $arSite[$site_id]['DIR'];
95 $r['SERVER_NAME'] = $arSite[$site_id]['SERVER_NAME'];
96
97 if ($r['SITE_URL'] <> '')
98 {
99 $r['URL'] = $r['SITE_URL'];
100 }
101
102 if (mb_substr($r['URL'], 0, 1) == '=')
103 {
104 foreach (GetModuleEvents('search', 'OnSearchGetURL', true) as $arEvent)
105 {
106 $newUrl = ExecuteModuleEventEx($arEvent, [$r]);
107 if (isset($newUrl))
108 {
109 $r['URL'] = $newUrl;
110 }
111 }
112 }
113
114 $r['URL'] = str_replace(
115 ['#LANG#', '#SITE_DIR#', '#SERVER_NAME#'],
116 [$r['DIR'], $r['DIR'], $r['SERVER_NAME']],
117 $r['URL']
118 );
119 $r['URL'] = preg_replace("'(?<!:)/+'s", '/', $r['URL']);
120
121 $r['NAME'] = htmlspecialcharsEx($r['TITLE']);
122
123 $preg_template = '/(^|[^' . $this->_arStemFunc['pcre_letters'] . '])(' . str_replace('/', '\\/', implode('|', array_map('preg_quote', array_keys($this->_arPhrase)))) . ')/iu';
124 if (preg_match_all($preg_template, mb_strtoupper($r['NAME']), $arMatches, PREG_OFFSET_CAPTURE))
125 {
126 $c = count($arMatches[2]);
127 for ($j = $c - 1; $j >= 0; $j--)
128 {
129 $prefix = substr($r['NAME'], 0, $arMatches[2][$j][1]);
130 $instr = substr($r['NAME'], $arMatches[2][$j][1], strlen($arMatches[2][$j][0]));
131 $suffix = substr($r['NAME'], $arMatches[2][$j][1] + strlen($arMatches[2][$j][0]), strlen($r['NAME']));
132 $r['NAME'] = $prefix . '<b>' . $instr . '</b>' . $suffix;
133 }
134 }
135 }
136
137 return $r;
138 }
139
140 public static function MakeFilterUrl($prefix, $arFilter)
141 {
142 if (!is_array($arFilter))
143 {
144 return '&' . urlencode($prefix) . '=' . urlencode($arFilter);
145 }
146 else
147 {
148 $url = '';
149 foreach ($arFilter as $key => $value)
150 {
151 $url .= CSearchTitle::MakeFilterUrl($prefix . '[' . $key . ']', $value);
152 }
153 return $url;
154 }
155 }
156
157 function searchTitle($phrase = '', $nTopCount = 5, $arParams = [], $bNotFilter = false, $order = '')
158 {
159 $DB = CDatabase::GetModuleConnection('search');
160 $bOrderByRank = ($order == 'rank');
161
162 $sqlHaving = [];
163 $sqlWords = [];
164 if (!empty($this->_arPhrase))
165 {
166 $last = true;
167 foreach (array_reverse($this->_arPhrase, true) as $word => $pos)
168 {
169 if ($last && !preg_match("/[\\n\\r \\t]$/", $phrase))
170 {
171 $last = false;
172 if (mb_strlen($word) >= $this->minLength)
173 {
174 $s = $sqlWords[] = "ct.WORD like '" . $DB->ForSQL($word) . "%'";
175 }
176 else
177 {
178 $s = '';
179 }
180 }
181 else
182 {
183 $s = $sqlWords[] = "ct.WORD = '" . $DB->ForSQL($word) . "'";
184 }
185
186 if ($s)
187 {
188 $sqlHaving[] = '(sum(case when ' . $s . ' then 1 else 0 end) > 0)';
189 }
190 }
191 }
192
193 if (!empty($sqlWords))
194 {
195 $bIncSites = false;
196 $strSqlWhere = CSearch::__PrepareFilter($arParams, $bIncSites);
197 if ($bNotFilter)
198 {
199 if (!empty($strSqlWhere))
200 {
201 $strSqlWhere = 'NOT (' . $strSqlWhere . ')';
202 }
203 else
204 {
205 $strSqlWhere = '1=0';
206 }
207 }
208
209 $strSql = "
210 SELECT
211 sc.ID
212 ,sc.MODULE_ID
213 ,sc.ITEM_ID
214 ,sc.TITLE
215 ,sc.PARAM1
216 ,sc.PARAM2
217 ,sc.DATE_CHANGE
218 ,sc.URL as URL
219 ,scsite.URL as SITE_URL
220 ,scsite.SITE_ID
221 ,case when position('" . $DB->ForSQL(mb_strtoupper($phrase)) . "' in upper(sc.TITLE)) > 0 then 1 else 0 end RANK1
222 ,count(1) RANK2
223 ,min(ct.POS) RANK3
224 FROM
225 b_search_content_title ct
226 inner join b_search_content sc on sc.ID = ct.SEARCH_CONTENT_ID
227 INNER JOIN b_search_content_site scsite ON sc.ID = scsite.SEARCH_CONTENT_ID and ct.SITE_ID = scsite.SITE_ID
228 WHERE
229 " . CSearch::CheckPermissions('sc.ID') . "
230 AND ct.SITE_ID = '" . SITE_ID . "'
231 AND (" . implode(' OR ', $sqlWords) . ')
232 ' . (!empty($strSqlWhere) ? 'AND ' . $strSqlWhere : '') . '
233 GROUP BY
234 sc.ID, sc.MODULE_ID, sc.ITEM_ID, sc.TITLE, sc.PARAM1, sc.PARAM2, sc.DATE_CHANGE, sc.URL, scsite.URL, scsite.SITE_ID
235 ' . (count($sqlHaving) > 1 ? 'HAVING ' . implode(' AND ', $sqlHaving) : '') . '
236 ORDER BY ' . (
237 $bOrderByRank ?
238 'RANK1 DESC, RANK2 DESC, RANK3 ASC, TITLE' :
239 'DATE_CHANGE DESC, RANK1 DESC, RANK2 DESC, RANK3 ASC, TITLE'
240 ) . '
241 LIMIT ' . ($nTopCount + 1) . '
242 ';
243
244 $r = $DB->Query($strSql);
245 parent::__construct($r);
246 return true;
247 }
248 else
249 {
250 return false;
251 }
252 }
253}
$arParams
Определения access_dialog.php:21
$DB
Определения dbresult.php:40
static getInstance()
Определения full_text.php:15
Определения title.php:4
Search($phrase='', $nTopCount=5, $arParams=[], $bNotFilter=false, $order='')
Определения title.php:15
searchTitle($phrase='', $nTopCount=5, $arParams=[], $bNotFilter=false, $order='')
Определения title.php:157
$minLength
Определения title.php:7
$_arStemFunc
Определения title.php:6
__construct($res=null)
Определения title.php:9
$_arPhrase
Определения title.php:5
background position
Определения file_new.php:745
$res
Определения filter_act.php:7
const SITE_DIR(!defined('LANG'))
Определения include.php:72
$order
Определения payment.php:8
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
const SITE_ID
Определения sonet_set_content_view.php:12
stemming_split($sText, $sLang='ru')
Определения stemming.php:122
stemming_init($sLang='ru')
Определения stemming.php:3