1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
mysql.php
См. документацию.
1<?php
3
5{
6 protected $error = '';
7 protected $errorno = 0;
8
9 public function connect($connectionString = '')
10 {
11 global $APPLICATION;
12 $DB = CDatabase::GetModuleConnection('search');
13
14 if (!$DB->TableExists('b_search_content_text'))
15 {
16 $APPLICATION->ThrowException(GetMessage('SEARCH_MYSQL_OLD_SCHEMA'));
17 return false;
18 }
19
20 if (!$DB->IndexExists('b_search_content_text', ['SEARCHABLE_CONTENT']))
21 {
22 $r = $DB->Query('create fulltext index fti on b_search_content_text(SEARCHABLE_CONTENT)', true);
23 if (!$r)
24 {
25 $APPLICATION->ThrowException(GetMessage('SEARCH_MYSQL_INDEX_CREATE_ERROR', ['#ERRSTR#' => $DB->db_Error]));
26 return false;
27 }
28 }
29
30 return true;
31 }
32
33 public function truncate()
34 {
35 $DB = CDatabase::GetModuleConnection('search');
36 $DB->Query('TRUNCATE TABLE b_search_content_text');
37 }
38
39 public function deleteById($ID)
40 {
41 $DB = CDatabase::GetModuleConnection('search');
42 $DB->Query('DELETE FROM b_search_content_text WHERE SEARCH_CONTENT_ID = ' . $ID);
43 }
44
45 public function update($ID, $arFields)
46 {
47 return $this->replace($ID, $arFields);
48 }
49
50 public function replace($ID, $arFields)
51 {
52 $DB = CDatabase::GetModuleConnection('search');
53
54 if (array_key_exists('SEARCHABLE_CONTENT', $arFields))
55 {
56 $text_md5 = md5($arFields['SEARCHABLE_CONTENT']);
57 $rsText = $DB->Query('SELECT SEARCH_CONTENT_MD5 FROM b_search_content_text WHERE SEARCH_CONTENT_ID = ' . $ID);
58 $arText = $rsText->Fetch();
59 if (!$arText || $arText['SEARCH_CONTENT_MD5'] !== $text_md5)
60 {
61 $DB->Query('
62 REPLACE INTO b_search_content_text
63 (SEARCH_CONTENT_ID, SEARCH_CONTENT_MD5, SEARCHABLE_CONTENT)
64 values
65 (' . $ID . ", '" . $DB->ForSql($text_md5) . "', '" . $DB->ForSql($arFields['SEARCHABLE_CONTENT']) . "')
66 ");
67 }
68 }
69 }
70
71 public function search($arParams, $aSort, $aParamsEx, $bTagsCloud)
72 {
73 $DB = CDatabase::GetModuleConnection('search');
74
75 $queryObject = $aParamsEx['QUERY_OBJECT'];
76 if ($queryObject->m_parsed_query == '( )' || $queryObject->m_parsed_query == '')
77 {
78 $this->error = GetMessage('SEARCH_ERROR3');
79 $this->errorno = 3;
80 return [];
81 }
82
83 $strQuery = $this->PrepareQuery($queryObject, $queryObject->m_parsed_query);
84 if ($strQuery == '(())' || $queryObject->m_parsed_query == '')
85 {
86 $this->error = GetMessage('SEARCH_ERROR3');
87 $this->errorno = 3;
88 return [];
89 }
90
91 $strTags = '';
92 if (array_key_exists('TAGS', $arParams))
93 {
94 $this->strTagsText = $arParams['TAGS'];
95 $arTags = explode(',', $arParams['TAGS']);
96 foreach ($arTags as $i => $strTag)
97 {
98 $arTags[$i] = trim($strTag, '"');
99 }
100
101 if ($arTags)
102 {
103 $strTags = '+(+"' . implode('" +"', $arTags) . '")';
104 }
105 }
106
107 if (($strQuery == '') && ($strTags <> ''))
108 {
109 $strQuery = $strTags;
110 $bTagsSearch = true;
111 }
112 else
113 {
114 $strQuery = preg_replace_callback('/&#(\\d+);/', 'chr', $strQuery);
115 $bTagsSearch = false;
116 }
117
118 $query = "match sct.SEARCHABLE_CONTENT against('" . $DB->ForSql($strQuery) . "' in boolean mode)";
119
120 $arSqlWhere = [];
121 if (is_array($aParamsEx) && !empty($aParamsEx))
122 {
123 foreach ($aParamsEx as $aParamEx)
124 {
125 $strSqlWhere = CSearch::__PrepareFilter($aParamEx, $bIncSites);
126 if ($strSqlWhere != '')
127 {
128 $arSqlWhere[] = $strSqlWhere;
129 }
130 }
131 }
132 if (!empty($arSqlWhere))
133 {
134 $arSqlWhere = [
135 "\n\t\t\t\t(" . implode(")\n\t\t\t\t\tOR(", $arSqlWhere) . "\n\t\t\t\t)",
136 ];
137 }
138
139 $strSqlWhere = CSearch::__PrepareFilter($arParams, $bIncSites);
140 if ($strSqlWhere != '')
141 {
142 array_unshift($arSqlWhere, $strSqlWhere);
143 }
144
145 $strSqlOrder = $this->__PrepareSort($aSort, 'sc.', $bTagsCloud);
146
147 if (!empty($arSqlWhere))
148 {
149 $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)";
150 }
151
152 if ($bTagsCloud)
153 {
154 $strSql = '
155 SELECT
156 stags.NAME
157 ,COUNT(DISTINCT stags.SEARCH_CONTENT_ID) as CNT
158 ,MAX(sc.DATE_CHANGE) DC_TMP
159 ,' . $DB->DateToCharFunction('MAX(sc.DATE_CHANGE)') . ' as FULL_DATE_CHANGE
160 ,' . $DB->DateToCharFunction('MAX(sc.DATE_CHANGE)', 'SHORT') . ' as DATE_CHANGE
161 FROM b_search_tags stags
162 INNER JOIN b_search_content sc ON (stags.SEARCH_CONTENT_ID=sc.ID)
163 INNER JOIN b_search_content_text sct ON sct.SEARCH_CONTENT_ID = sc.ID
164 INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID
165 WHERE
166 ' . CSearch::CheckPermissions('sc.ID') . '
167 AND (' . $query . ')
168 AND stags.SITE_ID = scsite.SITE_ID
169 ' . $strSqlWhere . '
170 GROUP BY
171 stags.NAME
172 ' . $strSqlOrder . '
173 ';
174 }
175 else
176 {
177 $strSql = '
178 SELECT
179 sct.SEARCH_CONTENT_ID
180 ,scsite.SITE_ID
181 ,' . $query . ' `RANK`
182 FROM
183 b_search_content_text sct
184 INNER JOIN b_search_content sc ON sc.ID = sct.SEARCH_CONTENT_ID
185 INNER JOIN b_search_content_site scsite ON sc.ID = scsite.SEARCH_CONTENT_ID
186 WHERE
187 ' . CSearch::CheckPermissions('sc.ID') . '
188 AND (' . $query . ')
189 ' . $strSqlWhere . '
190 ' . $strSqlOrder;
191 }
192
193 $r = $DB->Query($strSql);
194 $result = [];
195 while ($a = $r->Fetch())
196 {
197 $result[] = $a;
198 }
199
200 return $result;
201 }
202
203 function searchTitle($phrase = '', $arPhrase = [], $nTopCount = 5, $arParams = [], $bNotFilter = false, $order = '')
204 {
205 return false;
206 }
207
208 public function getErrorText()
209 {
210 return $this->error;
211 }
212
213 public function getErrorNumber()
214 {
215 return $this->errorno;
216 }
217
219 {
220 return new CSearchMySqlFormatter();
221 }
222
223 function __PrepareSort($aSort = [], $strSearchContentAlias = 'sc.', $bTagsCloud = false)
224 {
225 $arOrder = [];
226 if (!is_array($aSort))
227 {
228 $aSort = [$aSort => 'ASC'];
229 }
230
231 if ($bTagsCloud)
232 {
233 foreach ($aSort as $key => $ord)
234 {
235 $ord = mb_strtoupper($ord) <> 'ASC' ? 'DESC' : 'ASC';
236 $key = mb_strtoupper($key);
237 switch ($key)
238 {
239 case 'DATE_CHANGE':
240 $arOrder[] = 'DC_TMP ' . $ord;
241 break;
242 case 'NAME':
243 case 'CNT':
244 $arOrder[] = $key . ' ' . $ord;
245 break;
246 }
247 }
248 if (!$arOrder)
249 {
250 $arOrder[] = 'NAME ASC';
251 }
252 }
253 else
254 {
255 $this->flagsUseRatingSort = 0;
256 foreach ($aSort as $key => $ord)
257 {
258 $ord = mb_strtoupper($ord) <> 'ASC' ? 'DESC' : 'ASC';
259 $key = mb_strtoupper($key);
260 switch ($key)
261 {
262 case 'DATE_CHANGE':
263 if (!($this->flagsUseRatingSort & 0x01))
264 {
265 $this->flagsUseRatingSort = 0x02;
266 }
267 $arOrder[] = $strSearchContentAlias . $key . ' ' . $ord;
268 break;
269 case 'RANK':
270 if (!($this->flagsUseRatingSort & 0x02))
271 {
272 $this->flagsUseRatingSort = 0x01;
273 }
274 $arOrder[] = '`RANK` ' . $ord;
275 break;
276 case 'TITLE_RANK':
277 $arOrder[] = '`RANK` ' . $ord;
278 break;
279 case 'CUSTOM_RANK':
280 $arOrder[] = $strSearchContentAlias . $key . ' ' . $ord;
281 break;
282 case 'ID':
283 case 'MODULE_ID':
284 case 'ITEM_ID':
285 case 'TITLE':
286 case 'PARAM1':
287 case 'PARAM2':
288 case 'UPD':
289 case 'DATE_FROM':
290 case 'DATE_TO':
291 case 'URL':
292 if (!($this->flagsUseRatingSort & 0x01))
293 {
294 $this->flagsUseRatingSort = 0x02;
295 }
296 $arOrder[] = $strSearchContentAlias . $key . ' ' . $ord;
297 break;
298 }
299 }
300
301 if (!$arOrder)
302 {
303 $arOrder[] = 'CUSTOM_RANK DESC';
304 $arOrder[] = '`RANK` DESC';
305 $arOrder[] = $strSearchContentAlias . 'DATE_CHANGE DESC';
306 $this->flagsUseRatingSort = 0x01;
307 }
308 }
309
310 return ' ORDER BY ' . implode(', ', $arOrder);
311 }
312
313 function PrepareQuery($queryObject, $q)
314 {
315 $state = 0;
316 $qu = [];
317 $n = 0;
318 $this->error = '';
319 $this->errorno = 0;
320
321 foreach (preg_split('/ +/', $q) as $t)
322 {
323 if ($state === 0)
324 {
325 if (($t === '||') || ($t === '&&') || ($t === ')'))
326 {
327 $this->error = GetMessage('SEARCH_ERROR2') . ' ' . $t;
328 $this->errorno = 2;
329 break;
330 }
331 elseif ($t === '!')
332 {
333 $qu[] = ' -';
334 $p = count($qu) - 2;
335 if (isset($qu[$p]) && $qu[$p] === ' +')
336 {
337 $qu[$p] = '';
338 }
339 }
340 elseif ($t === '(')
341 {
342 $n++;
343 $p = count($qu) - 1;
344 if (isset($qu[$p]) && $qu[$p] === '(')
345 {
346 $qu[] = '';
347 }
348 $qu[] = '(';
349 }
350 else
351 {
352 $state = 1;
353 if (isset($queryObject->m_kav[$t]))
354 {
355 $t = '"' . $queryObject->m_kav[$t] . '"';
356 }
357 else
358 {
359 if (preg_match('/[^\w\d]/u', $t))
360 {
361 $t = preg_replace('/[^\w\d]+$/u', '', $t);
362 $t = preg_replace('/^[^\w\d]+/u', '', $t);
363 if ($t === '')
364 {
365 continue;
366 }
367 $t = '(+' . preg_replace('/[^\w\d]+/u', ' +', $t) . ($queryObject->bStemming ? '*' : '') . ')';
368 }
369 elseif ($queryObject->bStemming)
370 {
371 $t .= '*';
372 }
373 }
374 $p = count($qu) - 1;
375 if (!isset($qu[$p]) || $qu[$p] !== ' -')
376 {
377 $qu[] = '';
378 }
379 $qu[] = $t;
380 }
381 }
382 else
383 {
384 if (($t === '||') || ($t === '&&'))
385 {
386 $state = 0;
387 if ($t === '||')
388 {
389 $qu[] = ' ';
390 }
391 else
392 {
393 $qu[] = ' +';
394 $p = count($qu) - 1;
395 while (isset($qu[$p]) && $qu[$p] !== ')')
396 {
397 $p--;
398 }
399 $nn = 1;
400 while (isset($qu[$p]) && $nn)
401 {
402 $p--;
403 if ($qu[$p] === '(')
404 {
405 $nn--;
406 }
407 if ($qu[$p] === ')')
408 {
409 $nn++;
410 }
411 }
412 if (isset($qu[$p - 1]) && $qu[$p - 1] === '')
413 {
414 $qu[$p - 1] = ' +';
415 }
416 }
417 }
418 elseif ($t === ')')
419 {
420 $n--;
421 $qu[] = ')';
422 }
423 else
424 {
425 $this->error = GetMessage('SEARCH_ERROR2') . ' ' . $t;
426 $this->errorno = 2;
427 break;
428 }
429 }
430 }
431
432 if (($this->error === '') && ($n !== 0))
433 {
434 $this->error = GetMessage('SEARCH_ERROR1');
435 $this->errorno = 1;
436 }
437
438 if ($this->error != '')
439 {
440 return '';
441 }
442
443 return implode($qu);
444 }
445}
446
448{
449 function format($r)
450 {
451 if ($r)
452 {
453 if (array_key_exists('CNT', $r))
454 {
455 return $r;
456 }
457 elseif (array_key_exists('SEARCH_CONTENT_ID', $r))
458 {
459 return $this->formatRow($r);
460 }
461 }
462 }
463
464 function formatRow($r)
465 {
466 $DB = CDatabase::GetModuleConnection('search');
467
468 $rs = $DB->Query('
469 select
470 sc.ID
471 ,sc.MODULE_ID
472 ,sc.ITEM_ID
473 ,sc.TITLE
474 ,sc.TAGS
475 ,sc.BODY
476 ,sc.PARAM1
477 ,sc.PARAM2
478 ,sc.UPD
479 ,sc.DATE_FROM
480 ,sc.DATE_TO
481 ,sc.URL
482 ,sc.CUSTOM_RANK
483 ,' . $DB->DateToCharFunction('sc.DATE_CHANGE') . ' as FULL_DATE_CHANGE
484 ,' . $DB->DateToCharFunction('sc.DATE_CHANGE', 'SHORT') . ' as DATE_CHANGE
485 ,scsite.SITE_ID
486 ,scsite.URL SITE_URL
487 ,sc.USER_ID
488 from b_search_content sc
489 INNER JOIN b_search_content_site scsite ON sc.ID=scsite.SEARCH_CONTENT_ID
490 where ID = ' . $r['SEARCH_CONTENT_ID'] . "
491 and scsite.SITE_ID = '" . $r['SITE_ID'] . "'
492 ");
493 $r = $rs->Fetch();
494
495 return $r;
496 }
497}
$arParams
Определения access_dialog.php:21
global $APPLICATION
Определения include.php:80
static __PrepareFilter($arFilter, &$bIncSites, $strSearchContentAlias='sc.')
Определения search.php:2149
static CheckPermissions($FIELD='sc.ID')
Определения search.php:2660
Определения full_text.php:105
Определения full_text.php:4
Определения mysql.php:448
format($r)
Определения mysql.php:449
formatRow($r)
Определения mysql.php:464
Определения mysql.php:5
searchTitle($phrase='', $arPhrase=[], $nTopCount=5, $arParams=[], $bNotFilter=false, $order='')
Определения mysql.php:203
getErrorNumber()
Определения mysql.php:213
update($ID, $arFields)
Определения mysql.php:45
getErrorText()
Определения mysql.php:208
PrepareQuery($queryObject, $q)
Определения mysql.php:313
getRowFormatter()
Определения mysql.php:218
$errorno
Определения mysql.php:7
connect($connectionString='')
Определения mysql.php:9
__PrepareSort($aSort=[], $strSearchContentAlias='sc.', $bTagsCloud=false)
Определения mysql.php:223
deleteById($ID)
Определения mysql.php:39
truncate()
Определения mysql.php:33
replace($ID, $arFields)
Определения mysql.php:50
$error
Определения mysql.php:6
search($arParams, $aSort, $aParamsEx, $bTagsCloud)
Определения mysql.php:71
$arFields
Определения dblapprove.php:5
$result
Определения get_property_values.php:14
$arPhrase
Определения get_search.php:37
$query
Определения get_search.php:11
if($ajaxMode) $ID
Определения get_user.php:27
$p
Определения group_list_element_edit.php:23
global $DB
Определения cron_frame.php:29
IncludeModuleLangFile($filepath, $lang=false, $bReturnArray=false)
Определения tools.php:3778
GetMessage($name, $aReplace=null)
Определения tools.php:3397
$order
Определения payment.php:8
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
if(empty($signedUserToken)) $key
Определения quickway.php:257
$i
Определения factura.php:643
</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."%"
Определения waybill.php:936
else $a
Определения template.php:137
$rs
Определения action.php:82
$n
Определения update_log.php:107