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