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
9 years ago
|
<?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%%')";
|
||
8 years ago
|
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%%')";
|
||
9 years ago
|
|
||
|
/**
|
||
|
* ВНУТРЕННИЕ МЕТОДЫ
|
||
|
*/
|
||
|
|
||
|
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;
|
||
|
|
||
8 years ago
|
$sql = "
|
||
9 years ago
|
SELECT SQL_CALC_FOUND_ROWS
|
||
8 years ago
|
f1.document_id,
|
||
|
(SELECT CONCAT_WS('', f1.field_value, NULLIF(f2.field_value, ''))) AS field_value,
|
||
9 years ago
|
doc.document_title,
|
||
|
doc.document_published,
|
||
8 years ago
|
doc.document_count_view,
|
||
9 years ago
|
doc.document_in_search
|
||
8 years ago
|
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
|
||
9 years ago
|
" . $where . "
|
||
|
AND doc.document_in_search = '1'
|
||
|
AND doc.document_status = '1'
|
||
|
AND rub.rubric_field_search = '1'
|
||
|
GROUP BY doc.Id
|
||
8 years ago
|
ORDER BY doc.rubric_id ASC
|
||
9 years ago
|
LIMIT " . $start . "," . $limit
|
||
8 years ago
|
;
|
||
|
|
||
|
$query_feld = $AVE_DB->Query($sql);
|
||
|
|
||
|
//Debug::_echo($sql);
|
||
9 years ago
|
|
||
6 years ago
|
$num = $AVE_DB->NumAllRows($sql);
|
||
9 years ago
|
$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,
|
||
8 years ago
|
document_count_view,
|
||
9 years ago
|
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;
|
||
|
}
|
||
|
}
|
||
|
?>
|