You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
380 lines
9.7 KiB
380 lines
9.7 KiB
<?php |
|
|
|
/** |
|
* AVE.cms - Модуль Поиск |
|
* |
|
* @package AVE.cms |
|
* @subpackage module_Search |
|
* @filesource |
|
*/ |
|
|
|
class Search |
|
{ |
|
|
|
/** |
|
* СВОЙСТВА |
|
*/ |
|
|
|
var $_limit = 15; |
|
var $_adminlimit = 1000; |
|
var $_highlight = 1; |
|
var $_allowed_tags = ''; |
|
var $_disallowed_tags = ''; |
|
var $_search_string = ''; |
|
var $_stem_words = array(); |
|
var $_like_t = "(doc.document_title LIKE '%%%s%%')"; |
|
var $_not_like_t = "(doc.document_title LIKE '%%%s%%')"; |
|
var $_like = "(CONCAT_WS('', f1.field_value, NULLIF(f2.field_value, '')) LIKE '%%%s%%')"; |
|
var $_not_like = "(CONCAT_WS('', f1.field_value, NULLIF(f2.field_value, '')) NOT LIKE '%%%s%%')"; |
|
|
|
/** |
|
* ВНУТРЕННИЕ МЕТОДЫ |
|
*/ |
|
|
|
function _searchSpecialchars($string) |
|
{ |
|
$string = stripslashes($string); |
|
$string = str_replace ( '"', '"', $string ); |
|
$string = addslashes($string); |
|
$string = urldecode($string); |
|
|
|
return $string; |
|
} |
|
|
|
function _create_string_like(&$word, $key, $type='') |
|
{ |
|
global $stemmer; |
|
|
|
$type_search = (isset($_REQUEST['ts']) ? $_REQUEST['ts'] : 0); |
|
|
|
switch ($type) |
|
{ |
|
case '-': |
|
$word = $stemmer->stem_word(mb_substr($word, 1)); |
|
if (isset($type_search) && $type_search != 0){ |
|
$format_string = $this->_not_like_t; |
|
} else { |
|
$format_string = $this->_not_like; |
|
} |
|
break; |
|
|
|
case '+': |
|
$word = $stemmer->stem_word(mb_substr($word, 1)); |
|
if (isset($type_search) && $type_search != 0){ |
|
$format_string = $this->_like_t; |
|
} else { |
|
$format_string = $this->_like; |
|
} |
|
$this->_stem_words[] = $word; |
|
break; |
|
|
|
default: |
|
$word = $stemmer->stem_word($word); |
|
if (isset($type_search) && $type_search != 0){ |
|
$format_string = $this->_like_t; |
|
} else { |
|
$format_string = $this->_like; |
|
} |
|
$this->_stem_words[] = $word; |
|
break; |
|
} |
|
|
|
$word = sprintf($format_string, $word, $this->_searchSpecialchars($word)); |
|
} |
|
|
|
/** |
|
* ВНЕШНИЕ МЕТОДЫ |
|
*/ |
|
|
|
function searchResultGet($tpl_dir, $lang_file) |
|
{ |
|
global $AVE_DB, $AVE_Template; |
|
|
|
$AVE_Template->config_load($lang_file); |
|
|
|
define('MODULE_TITLE', $AVE_Template->get_config_vars('SEARCH_RESULTS')); |
|
|
|
$stem_words = array(); |
|
|
|
$tmp = preg_replace('/[^\x20-\xFF]|[><!?.,;=-]/', ' ', $_REQUEST['query']); |
|
|
|
$this->_search_string = trim(preg_replace('/ +/', ' ', stripslashes($tmp))); |
|
|
|
if (mb_strlen($this->_search_string) > 2) |
|
{ |
|
// экранирование для LIKE |
|
$tmp = str_replace('\\', '\\\\', $this->_search_string); |
|
$tmp = addcslashes(addslashes($tmp), '%_'); |
|
$tmp = preg_replace('/ +/', ' ', $tmp); |
|
$tmp = preg_split('/\s+/', $tmp); |
|
|
|
$where = ''; |
|
|
|
if (sizeof($tmp)) |
|
{ |
|
$_tmp = preg_grep('/^[^\+|-].{3,}/', $tmp); |
|
array_walk($_tmp, array(&$this,'_create_string_like')); |
|
// + |
|
$__tmp = preg_grep('/^\+.{3,}/', $tmp); |
|
array_walk($__tmp, array(&$this,'_create_string_like'), '+'); |
|
// - |
|
$___tmp = preg_grep('/^-.{3,}/', $tmp); |
|
array_walk($___tmp, array(&$this,'_create_string_like'), '-'); |
|
|
|
if (!empty($_tmp)) |
|
{ |
|
$where = 'WHERE (' . implode((isset($_REQUEST['or']) && 1 == $_REQUEST['or']) ? ' OR ' : ' AND ', $_tmp) . ')'; |
|
if (!empty($__tmp)) |
|
{ |
|
$where .= ' AND ' . implode(' AND ', array_merge($__tmp, $___tmp)); |
|
} |
|
} |
|
elseif (!empty($__tmp)) |
|
{ |
|
$where = 'WHERE ' . implode(' AND ', array_merge($__tmp, $___tmp)); |
|
} |
|
} |
|
|
|
$num = 0; |
|
if ($where != '') |
|
{ |
|
$limit = $this->_limit; |
|
$start = get_current_page() * $limit - $limit; |
|
|
|
$sql = " |
|
SELECT SQL_CALC_FOUND_ROWS |
|
f1.document_id, |
|
(SELECT CONCAT_WS('', f1.field_value, NULLIF(f2.field_value, ''))) AS field_value, |
|
doc.document_title, |
|
doc.document_published, |
|
doc.document_count_view, |
|
doc.document_in_search |
|
FROM |
|
" . PREFIX . "_document_fields AS f1 |
|
LEFT JOIN |
|
" . PREFIX . "_document_fields_text AS f2 |
|
ON f1.document_id = f2.document_id |
|
LEFT JOIN |
|
" . PREFIX . "_documents AS doc |
|
ON f1.document_id = doc.Id |
|
LEFT JOIN |
|
" . PREFIX . "_rubric_fields AS rub |
|
ON f1.rubric_field_id = rub.Id |
|
" . $where . " |
|
AND doc.document_in_search = '1' |
|
AND doc.document_status = '1' |
|
AND rub.rubric_field_search = '1' |
|
GROUP BY doc.Id |
|
ORDER BY doc.rubric_id ASC |
|
LIMIT " . $start . "," . $limit |
|
; |
|
|
|
$query_feld = $AVE_DB->Query($sql); |
|
|
|
//Debug::_echo($sql); |
|
|
|
$num = $AVE_DB->NumAllRows(); |
|
$pages = @ceil($num / $limit); |
|
|
|
$sw = addslashes(mb_strtolower($this->_search_string)); |
|
|
|
$exist = $AVE_DB->Query(" |
|
SELECT 1 |
|
FROM " . PREFIX . "_module_search |
|
WHERE search_query = '" . $sw . "' |
|
LIMIT 1 |
|
")->NumRows(); |
|
|
|
if ($exist) |
|
{ |
|
$AVE_DB->Query(" |
|
UPDATE " . PREFIX . "_module_search |
|
SET |
|
search_found = '" . (int)$num . "', |
|
search_count = search_count+1 |
|
WHERE search_query = '" . $sw . "' |
|
"); |
|
} |
|
else |
|
{ |
|
$AVE_DB->Query(" |
|
INSERT |
|
INTO " . PREFIX . "_module_search |
|
SET |
|
Id = '', |
|
search_found = '" . (int)$num . "', |
|
search_query = '" . $sw . "', |
|
search_count = 1 |
|
"); |
|
} |
|
if ($num > $limit) |
|
{ |
|
$page_nav = '<a class="page_nav" href="index.php?module=search&query=' |
|
. urlencode($this->_search_string) |
|
. ($type_search ? '&ts=1' : '') |
|
. ($_REQUEST['or'] ? '&or=1' : '') |
|
. '&page={s}">{t}</a>'; |
|
$page_nav = get_pagination($pages, 'page', $page_nav); |
|
} |
|
$AVE_Template->assign('q_navi', $page_nav); |
|
} |
|
|
|
if ($num > 0) |
|
{ |
|
$modul_search_results = array(); |
|
|
|
array_walk($this->_stem_words, create_function('&$val','$val=preg_quote(stripslashes(stripslashes(str_replace("\"",""",$val))),"/");')); |
|
$regex_snapshot = '/.{0,100}[^\s]*' . implode('[^\s]*.{0,100}|.{0,100}[^\s]*', $this->_stem_words) . '[^\s]*.{0,100}/iu'; |
|
$regex_highlight = '/[^\s]*' . implode('[^\s]*|[^\s]*', $this->_stem_words) . '[^\s]*/iu'; |
|
|
|
$doctime = get_settings('use_doctime') ? ("AND document_published <= " . time() . " AND (document_expire = 0 OR document_expire >= " . time() . ")") : ''; |
|
|
|
while ($row_feld = $query_feld->FetchRow()) |
|
{ |
|
$sql = $AVE_DB->Query(" |
|
SELECT |
|
Id, |
|
document_title, |
|
document_alias, |
|
document_published, |
|
document_count_view, |
|
rubric_id |
|
FROM " . PREFIX . "_documents |
|
WHERE Id = '" . $row_feld->document_id . "' |
|
AND document_deleted = '0' |
|
AND document_status = '1' |
|
" . $doctime |
|
); |
|
while ($row = $sql->FetchRow()) |
|
{ |
|
$row->Text = $row_feld->field_value; |
|
$row->Text = strip_tags($row->Text, $this->_allowed_tags); |
|
|
|
$fo = array(); |
|
|
|
preg_match($regex_snapshot, $row->Text, $fo); |
|
|
|
$row->Text = $type_search ? '' : ''; |
|
|
|
while (list($key, $val) = @each($fo)) |
|
{ |
|
$row->Text .= $val . ($type_search ? '' : ''); |
|
} |
|
|
|
if (1 == $this->_highlight && !empty($this->_stem_words)) |
|
{ |
|
$row->Text = @preg_replace($regex_highlight, "<strong class=\"mod_search_highlight\">$0</strong>", $row->Text); |
|
} |
|
$row->document_alias = rewrite_link('index.php?id=' . $row->Id . '&doc=' . (empty($row->document_alias) ? prepare_url($row->document_title) : $row->document_alias)); |
|
|
|
$modul_search_results[$row->Id] = $row; |
|
} |
|
} |
|
|
|
$AVE_Template->assign('searchresults', $modul_search_results); |
|
} |
|
else |
|
{ |
|
$AVE_Template->assign('no_results', 1); |
|
} |
|
} |
|
else |
|
{ |
|
$AVE_Template->assign('no_results', 1); |
|
} |
|
|
|
if (!defined('MODULE_CONTENT')) |
|
{ |
|
$AVE_Template->assign('inc_path', BASE_DIR . '/modules/search/templates'); |
|
define('MODULE_CONTENT', $AVE_Template->fetch($tpl_dir . 'results.tpl')); |
|
} |
|
} |
|
|
|
function searchWordsShow($tpl_dir) |
|
{ |
|
global $AVE_DB, $AVE_Template; |
|
|
|
$limit = $this->_adminlimit; |
|
|
|
$sort = ' ORDER BY search_query ASC'; |
|
$sort_navi = ''; |
|
|
|
if (!empty($_REQUEST['sort'])) |
|
{ |
|
switch ($_REQUEST['sort']) |
|
{ |
|
case 'begriff_desc' : |
|
$sort = ' ORDER BY search_query DESC'; |
|
$sort_navi = '&sort=begriff_desc'; |
|
break; |
|
|
|
case 'begriff_asc' : |
|
$sort = ' ORDER BY search_query ASC'; |
|
$sort_navi = '&sort=begriff_asc'; |
|
break; |
|
|
|
case 'anzahl_desc' : |
|
$sort = ' ORDER BY search_count DESC'; |
|
$sort_navi = '&sort=anzahl_desc'; |
|
break; |
|
|
|
case 'anzahl_asc' : |
|
$sort = ' ORDER BY search_count ASC'; |
|
$sort_navi = '&sort=anzahl_asc'; |
|
break; |
|
|
|
case 'gefunden_desc' : |
|
$sort = ' ORDER BY search_found DESC'; |
|
$sort_navi = '&sort=gefunden_desc'; |
|
break; |
|
|
|
case 'gefunden_asc' : |
|
$sort = ' ORDER BY search_found ASC'; |
|
$sort_navi = '&sort=gefunden_asc'; |
|
break; |
|
} |
|
} |
|
|
|
$num = $AVE_DB->Query(" |
|
SELECT Id |
|
FROM " . PREFIX . "_module_search |
|
" . $sort |
|
)->NumRows(); |
|
|
|
$seiten = ceil($num / $limit); |
|
$start = get_current_page() * $limit - $limit; |
|
|
|
$items = array(); |
|
$sql = $AVE_DB->Query(" |
|
SELECT * |
|
FROM " . PREFIX . "_module_search |
|
" . $sort . " |
|
LIMIT " . $start . "," . $limit |
|
); |
|
while ($row = $sql->FetchRow()) |
|
{ |
|
array_push($items,$row); |
|
} |
|
|
|
if ($num > $limit) |
|
{ |
|
$page_nav = " <a class=\"pnav\" href=\"index.php?do=modules&action=modedit&mod=search&moduleaction=1" . $sort_navi . "&cp=" . SESSION . "&page={s}\">{t}</a> "; |
|
$page_nav = get_pagination($seiten, 'page', $page_nav); |
|
$AVE_Template->assign('page_nav', $page_nav); |
|
} |
|
|
|
$AVE_Template->assign('items', $items); |
|
$AVE_Template->assign('content', $AVE_Template->fetch($tpl_dir . 'words.tpl')); |
|
} |
|
|
|
function searchWordsDelete() |
|
{ |
|
global $AVE_DB; |
|
|
|
$AVE_DB->Query("DELETE FROM " . PREFIX . "_module_search"); |
|
|
|
header('Location:index.php?do=modules&action=modedit&mod=search&moduleaction=1&cp=' . SESSION); |
|
exit; |
|
} |
|
} |
|
?>
|