diff --git a/README.md b/README.md
index 498adaf..0a0cb0d 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,16 @@
-# search
+### search
-Модуль Поиск Только для AVE.CMS ALT
\ No newline at end of file
+## Модуль Поиск v2.26.0
+
+
+### Данный модуль позволяет организвать поиск необходимой информации на вашем сайте.
+
+ * Поиск информации осуществляется как по заголовкам документов, так и по содержимому. Для того, чтобы вывести форму для поиска на вашем сайте, разместите системный тег [mod_search] в нужном месте вашего шаблона сайта.
+
+### Changelog:
+
+02.09.2019 - версия 2.26.0 - Адаптация для версии AVE.CMS v3.26
+
+16.07.2016 - версия 2.1.1 - обновления от @MadDen
+
+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..ec15254
--- /dev/null
+++ b/class/search.php
@@ -0,0 +1,380 @@
+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;
+
+ $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($sql);
+ $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,
+ 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, "$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/info.php b/info.php
new file mode 100644
index 0000000..52ba89f
--- /dev/null
+++ b/info.php
@@ -0,0 +1,19 @@
+ 'search',
+ 'ModuleVersion' => '1.26.0',
+ 'ModuleAutor' => 'AVE.cms Team',
+ 'ModuleCopyright' => '© 2007-' . date('Y') . ' AVE.cms',
+ 'ModuleIsFunction' => 1,
+ 'ModuleTemplate' => 1,
+ 'ModuleAdminEdit' => 1,
+ 'ModuleFunction' => 'mod_search',
+ 'ModuleTag' => '[mod_search]',
+ 'ModuleTagLink' => null,
+ 'ModuleAveTag' => '#\\\[mod_search]#',
+ 'ModulePHPTag' => ""
+ );
+?>
\ 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..0820de8
--- /dev/null
+++ b/lang/ru.txt
@@ -0,0 +1,24 @@
+[name]
+MODULE_NAME = "Поиск"
+MODULE_DESCRIPTION = "Данный модуль позволяет организвать поиск необходимой информации на вашем сайте. Поиск информации осуществляется как по заголовкам документов, так и по содержимому. Для того, чтобы вывести форму для поиска на вашем сайте, разместите системный тег [mod_search] в нужном месте вашего шаблона сайта."
+
+[module]
+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..c29f434
--- /dev/null
+++ b/module.php
@@ -0,0 +1,63 @@
+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';
+ $AVE_Template->config_load($lang_file, 'module');
+
+ $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, 'module');
+
+ 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..425d739
--- /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 @@
+
{#SEARCH_NO_RESULTS#}
+{else} + {if $q_navi}{/if} + + {foreach from=$searchresults item=result} +{$result->Text}
{#SEARCH_VIEW#} | {#SEARCH_VIEW_BLANK#} {$result->document_count_view}