From 039147153b36257e059ee1e7fb7b3e707fc4a053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A1=D0=B5=D1=80=D0=B3=D0=B5=D0=B9=20=D0=92=D0=B0=D1=80?= =?UTF-8?q?=D0=BB=D0=B0=D0=BC=D0=BE=D0=B2?= Date: Fri, 10 Jun 2016 23:10:31 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=BC=D0=BE=D0=B4=D1=83=D0=BB=D1=8C=20=D0=9F=D0=BE?= =?UTF-8?q?=D0=B8=D1=81=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 ++ class.porter.php | 94 +++++++++ class.search.php | 369 +++++++++++++++++++++++++++++++++ index.php | 4 + lang/index.php | 4 + lang/ru.txt | 19 ++ module.php | 79 +++++++ sql.php | 46 ++++ templates/form.tpl | 5 + templates/form_big.tpl | 17 ++ templates/images/icoSearch.gif | Bin 0 -> 322 bytes templates/index.php | 4 + templates/results.tpl | 16 ++ templates/words.tpl | 71 +++++++ 14 files changed, 742 insertions(+) create mode 100644 README.md create mode 100644 class.porter.php create mode 100644 class.search.php create mode 100644 index.php create mode 100644 lang/index.php create mode 100644 lang/ru.txt create mode 100644 module.php create mode 100644 sql.php create mode 100644 templates/form.tpl create mode 100644 templates/form_big.tpl create mode 100644 templates/images/icoSearch.gif create mode 100644 templates/index.php create mode 100644 templates/results.tpl create mode 100644 templates/words.tpl diff --git a/README.md b/README.md new file mode 100644 index 0000000..5104e2a --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +## search + +# Модуль Поиск v2.1.0 + + +## Данный модуль позволяет организвать поиск необходимой информации на вашем сайте. + + * Поиск информации осуществляется как по заголовкам документов, так и по содержимому. Для того, чтобы вывести форму для поиска на вашем сайте, разместите системный тег [mod_search] в нужном месте вашего шаблона сайта. + +## Перед копированием модуля в папку modules, удалите файл README.md, копируйте только корневую папку sitemap со всем ее содержимым внутри! + +## Changelog: + +22.04.2014 - версия 2.1.0 \ No newline at end of file diff --git a/class.porter.php b/class.porter.php new file mode 100644 index 0000000..d211263 --- /dev/null +++ b/class.porter.php @@ -0,0 +1,94 @@ +Stem_Caching && isset($this->Stem_Cache[$word])) { + return $this->Stem_Cache[$word]; + } + $stem = $word; + do { + if (!preg_match($this->RVRE, $word, $p)) break; + $start = $p[1]; + $RV = $p[2]; + if (!$RV) break; + + # Step 1 + if (!$this->s($RV, $this->PERFECTIVEGROUND, '')) { + $this->s($RV, $this->REFLEXIVE, ''); + + if ($this->s($RV, $this->ADJECTIVE, '')) { + $this->s($RV, $this->PARTICIPLE, ''); + } else { + if (!$this->s($RV, $this->VERB, '')) + $this->s($RV, $this->NOUN, ''); + } + } + + # Step 2 + $this->s($RV, '/и$/', ''); + + # Step 3 + if ($this->m($RV, $this->DERIVATIONAL)) + $this->s($RV, '/ость?$/', ''); + + # Step 4 + if (!$this->s($RV, '/ь$/', '')) { + $this->s($RV, '/ейше?/', ''); + $this->s($RV, '/нн$/', 'н'); + } + + $stem = $start.$RV; + } while(false); + if ($this->Stem_Caching) $this->Stem_Cache[$word] = $stem; + return $stem; + } + + function stem_caching($parm_ref) + { + $caching_level = @$parm_ref['-level']; + if ($caching_level) { + if (!$this->m($caching_level, '/^[012]$/')) { + die(__CLASS__ . "::stem_caching() - Legal values are '0','1' or '2'. '$caching_level' is not a legal value"); + } + $this->Stem_Caching = $caching_level; + } + return $this->Stem_Caching; + } + + function clear_stem_cache() + { + $this->Stem_Cache = array(); + } +} + +?> \ No newline at end of file diff --git a/class.search.php b/class.search.php new file mode 100644 index 0000000..573b2b0 --- /dev/null +++ b/class.search.php @@ -0,0 +1,369 @@ +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]|[>_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; + + $query_feld = $AVE_DB->Query(" + SELECT SQL_CALC_FOUND_ROWS + document_id, + field_value, + doc.document_title, + doc.document_published, + doc.document_in_search + FROM " . PREFIX . "_document_fields + LEFT JOIN " . PREFIX . "_documents AS doc + ON document_id = doc.Id + LEFT JOIN " . PREFIX . "_rubric_fields AS rub + ON 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.document_published DESC + LIMIT " . $start . "," . $limit + ); + + $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 = '{t}'; + $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, + 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, "$0", $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 = " {t} "; + $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; + } +} +?> \ No newline at end of file diff --git a/index.php b/index.php new file mode 100644 index 0000000..4ca25aa --- /dev/null +++ b/index.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/lang/index.php b/lang/index.php new file mode 100644 index 0000000..4ca25aa --- /dev/null +++ b/lang/index.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/lang/ru.txt b/lang/ru.txt new file mode 100644 index 0000000..7851c7f --- /dev/null +++ b/lang/ru.txt @@ -0,0 +1,19 @@ +SEARCH_BUTTON = "Поиск" +SEARCH_IN_DESCRIPTION = "В тексте" +SEARCH_IN_TITLE = "В заголовках" +SEARCH_HELP = "Использование поиска

Используйте знак "+" для строгого включения слова в поиск.
Используйте знак "-" для исключения слова из поиска.

Обязательно используйте пробел перед знаками "+" и "-". " +SEARCH_USE_AND = "Используя "И"" +SEARCH_USE_OR = "Используя "ИЛИ"" +SEARCH_RESULTS = "Результаты поиска" +SEARCH_NO_RESULTS = "Извините, но по вашему запросу ничего не найдено." +SEARCH_PAGES = "Страницы: " +SEARCH_VIEW = "Показать" +SEARCH_VIEW_BLANK = "Показать в новом окне" + +SEARCH_MODULE_NAME = "Поиск" +SEARCH_MODULE_DESCRIPTION = "В данном разделе приведена полная статистика всех поисковых фраз, по которым осуществлялся поиск информации на сайте." +SEARCH_WORD = "Поисковая фраза" +SEARCH_QUERIES = "Выполненных запросов" +SEARCH_FOUND_DOCS = "Найдено документов" +SEARCH_DELETE_ITEMS = "Удалить историю" +SEARCH_DELETE_CONFIRM = "Вы уверены, что хотите удалить историю?" \ No newline at end of file diff --git a/module.php b/module.php new file mode 100644 index 0000000..68f3181 --- /dev/null +++ b/module.php @@ -0,0 +1,79 @@ +[mod_search] в нужном месте вашего шаблона сайта.'; + $modul['ModuleAutor'] = 'AVE.CMS Team'; + $modul['ModuleCopyright'] = '© 2007-2014 AVE.CMS'; + $modul['ModuleIsFunction'] = 1; + $modul['ModuleTemplate'] = 1; + $modul['ModuleAdminEdit'] = 1; + $modul['ModuleFunction'] = 'mod_search'; + $modul['ModuleTag'] = '[mod_search]'; + $modul['ModuleTagLink'] = null; + $modul['ModuleAveTag'] = '#\\\[mod_search]#'; + $modul['ModulePHPTag'] = ''; +} + +function mod_search() +{ + global $AVE_Template; + + if (isset($_REQUEST['module']) && $_REQUEST['module'] == 'search') $AVE_Template->assign('hide', 1); + $AVE_Template->display(BASE_DIR . '/modules/search/templates/form.tpl'); +} + +if (!defined('ACP') && (isset($_REQUEST['module']) && $_REQUEST['module'] == 'search')) +{ + global $stemmer; + + if (! @require_once(BASE_DIR . '/modules/search/class.search.php')) module_error(); + if (! @require_once(BASE_DIR . '/modules/search/class.porter.php')) module_error(); + + $tpl_dir = BASE_DIR . '/modules/search/templates/'; + $lang_file = BASE_DIR . '/modules/search/lang/' . $_SESSION['user_language'] . '.txt'; + + $search = new Search; + $stemmer = new Lingua_Stem_Ru(); + + $search->searchResultGet($tpl_dir, $lang_file); +} + +if (defined('ACP') && !empty($_REQUEST['moduleaction'])) +{ + if (! (is_file(BASE_DIR . '/modules/search/class.search.php') && + @require_once(BASE_DIR . '/modules/search/class.search.php'))) module_error(); + + $tpl_dir = BASE_DIR .'/modules/search/templates/'; + $lang_file = BASE_DIR .'/modules/search/lang/' . $_SESSION['admin_language'] . '.txt'; + + $search = new Search; + + $AVE_Template->config_load($lang_file); + + switch ($_REQUEST['moduleaction']) + { + case '1': + $search->searchWordsShow($tpl_dir); + break; + + case 'delwords': + $search->searchWordsDelete(); + break; + } +} + +?> \ No newline at end of file diff --git a/sql.php b/sql.php new file mode 100644 index 0000000..96e070b --- /dev/null +++ b/sql.php @@ -0,0 +1,46 @@ + \ No newline at end of file diff --git a/templates/form.tpl b/templates/form.tpl new file mode 100644 index 0000000..ee4ea20 --- /dev/null +++ b/templates/form.tpl @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/templates/form_big.tpl b/templates/form_big.tpl new file mode 100644 index 0000000..4d20bfa --- /dev/null +++ b/templates/form_big.tpl @@ -0,0 +1,17 @@ +
+
+ + +   + +
+ +
+ {#SEARCH_IN_DESCRIPTION#} + {#SEARCH_IN_TITLE#} + + {#SEARCH_USE_AND#} + {#SEARCH_USE_OR#} +
+
+
diff --git a/templates/images/icoSearch.gif b/templates/images/icoSearch.gif new file mode 100644 index 0000000000000000000000000000000000000000..53313d0bc1f08339ae455c230e5988b74ac3e964 GIT binary patch literal 322 zcmZ?wbhEHbiVvVdZ63ds_NSR|NqZ`11SDvVPs%1XV3x3 zgZ#w67JuOOS(gnpY{CnT6gS^Y+wAMCd4a(}FR(GFnS;}$?^D{0y)7!YQe~Kqv@D&P z@}_Za3)k#K8?GfSqNW;x+&ru%W?EjdW*oX^zD7F9e9Y{U5=^Ehrpfcn8RyJTHsyC@ Gum%7aF_P*4 literal 0 HcmV?d00001 diff --git a/templates/index.php b/templates/index.php new file mode 100644 index 0000000..4ca25aa --- /dev/null +++ b/templates/index.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/templates/results.tpl b/templates/results.tpl new file mode 100644 index 0000000..25689e2 --- /dev/null +++ b/templates/results.tpl @@ -0,0 +1,16 @@ +

{#SEARCH_RESULTS#}

+ +{if $no_results==1} +

{#SEARCH_NO_RESULTS#}

+{else} + {if $q_navi}{/if} + + {foreach from=$searchresults item=result} +

{$result->document_title|escape} {$result->document_published|date_format:$DATE_FORMAT|pretty_date}

+
{$result->Text}
{#SEARCH_VIEW#} | {#SEARCH_VIEW_BLANK#} {$result->document_count_view}

+ {/foreach} + + {if $q_navi}{/if} +{/if} + +{include file="$inc_path/form_big.tpl"} \ No newline at end of file diff --git a/templates/words.tpl b/templates/words.tpl new file mode 100644 index 0000000..8abbdca --- /dev/null +++ b/templates/words.tpl @@ -0,0 +1,71 @@ + + +
{#SEARCH_MODULE_NAME#}
+ +
+
+ {#SEARCH_MODULE_DESCRIPTION#} +
+
+ + + +
+
{#SEARCH_MODULE_NAME#}
+ + + + + + + + + + {foreach from=$items item=item} + + + + + + {/foreach} + +
{#SEARCH_WORD#}{#SEARCH_QUERIES#}{#SEARCH_FOUND_DOCS#}
{$item->search_query|escape}{$item->search_count}{$item->search_found}
+
+
+
+
+ +
+
+
+ +