Модуль Поиск v2.26.0
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.

378 lines
9.6 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 ( '"', '&quot;', $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_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&amp;query='
. urlencode($this->_search_string)
. ($type_search ? '&amp;ts=1' : '')
. ($_REQUEST['or'] ? '&amp;or=1' : '')
. '&amp;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("\"","&quot;",$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,
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 . '&amp;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 = '&amp;sort=begriff_desc';
break;
case 'begriff_asc' :
$sort = ' ORDER BY search_query ASC';
$sort_navi = '&amp;sort=begriff_asc';
break;
case 'anzahl_desc' :
$sort = ' ORDER BY search_count DESC';
$sort_navi = '&amp;sort=anzahl_desc';
break;
case 'anzahl_asc' :
$sort = ' ORDER BY search_count ASC';
$sort_navi = '&amp;sort=anzahl_asc';
break;
case 'gefunden_desc' :
$sort = ' ORDER BY search_found DESC';
$sort_navi = '&amp;sort=gefunden_desc';
break;
case 'gefunden_asc' :
$sort = ' ORDER BY search_found ASC';
$sort_navi = '&amp;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;
}
}
?>