update v3.32 (add module aliases)

This commit is contained in:
2026-04-22 23:57:56 +05:00
parent 6113f0e86d
commit 9a73b3536c
7 changed files with 398 additions and 97 deletions

View File

@@ -1,7 +1,22 @@
### Альтернативная версия AVE.CMS v3.31 ALT
### Альтернативная версия AVE.CMS v3.32 ALT
### Changelog:
#### Версия v3.32 ALT - Добавлено Управление редиректами модулей. Теперь каждой системной ссылке модуля можно добавить ЧПУ алиас. Создан интерфейс «История алиасов», где можно массово удалять старые записи или вручную добавлять новые редиректы с кодами 301 (постоянный) или 302 (временный).
* Пример создания алиаса для модуля Поиск - ссылка на страницу результатов поиска:
* Установите модуль Поиск.
* Перейдите в раздел Управление модулями->Редактирование алиасов.
* На открывшейся странице делаем клик по кнопке "Создать редирект"
* В открывшемся модальном окне "Создать редирект" заполняем ВСЕ поля:
* Системное имя модуля: ```search``` (можно брать название корневой папки модуля)
* Название редиректа: ```Страница с результатами поиска```
* Системный Action: ```search``` - берется из системной ссылки модуля
* Системный URL: ```index.php?module=search&query=``` - берется из системной ссылки модуля. Если вы не знаете URL использующийся в шаблонах модуля , можете просто скопировать и вставить URL из браузера со страницы вывода результатов поиска ```https://домен.xx/?module=search&query=```. Скрипт обработает вашу ссылку и оставит в поле Системный URL: ```?module=search&query=```, а при сохранении подставит в начало ```index.php``` и , финальная ссылка (после сохранения) станет такой же как приведено в самом начале ```index.php?module=search&query=``` т.е. системной ссылкой модуля. Запрещается использовать ссылки внешних доменов, скрипт просто заменит такие ссылки на ```index.php```
* Основной ЧПУ алиас: укажите любой желаемый алиас, по которому вы хотите открывать страницу поиска, например ```search/```
* Привязка к документу: если вы хотите использовать алиас ```search/``` в документе, вы можете сразу выбрать нужный документ и сохранить его, что-бы спустя время понимать где расположен и используется этот алиас.
* Доступ в админпанель: вы можете создавать алиасы, ведущие , например, из паблика в админпанель. Доступ в админпанель по таким алиасам получает только Администратор.
* После заполнения этих полей, делаем клик по кнопке "Сохранить изменения" - редирект создан. Наберите в адресной строке браузера ```https://домен.xx/search/``` и вы попадете на страницу результатов поиска.
* История алиасов. После того как вы создали редирект, станет доступно создание дополнительных алиасов для этого редиректа. Кликните по иконке "История", в открывшемся модальном окне "Управление редиректом Страница с результатами поиска" можно добавить варианты алиасов , например ```find/``` и в этом случае при наборе в адресной строке браузера уже ```https://домен.xx/find/``` будет переадресация на страницу ```https://домен.xx/search/``` с кодом 301 или 302 (в зависимости от вашего выбора).
#### Версия v3.31 ALT - Готова для работы в среде PHP-8.4.x; исправлены ошибки тянущиеся из прошлых версий. Добавлен PHPMailer для отправки почты методами mail и sendmail, Symfony Mailer работает исключительно с SMTP протоколом.
#### Версия v3.30 ALT - Шаблонизатор Smarty обновлен до версии 5.6
#### Версия v3.29 ALT - удален устаревший Swift Mailer, на замену ему интегрирован Symfony Mailer;

View File

@@ -1,5 +1,8 @@
[modules]
MODULES_SUB_TITLE = "Управление модулями"
MODULES_ALIASES = "Управление редиректами модулей"
MODULES_ALIASES_TITLE = "В данном разделе приведен список всех модулей, у которых присутвуют внутренние редиректы.<br>
Здесь Вы можете выполнить основные операции как: Создание, Просмотр, Редактирование, Удаление редиректа."
MODULES_TIP = "В данном разделе приведен список всех доступных модулей в системе. Здесь Вы можете установить, отключить, обновить любой из модулей, а также выполнить дополнительные, персональные настройки для любого из модулей."
MODULES_NAME = "Название модуля"
MODULES_INFO = "Информация"
@@ -19,6 +22,7 @@ MODULES_UPDATE = "Обновить модуль"
MODULES_STOP = "Отключить модуль"
MODULES_START = "Включить модуль"
MODULES_BUTTON_SAVE = "Сохранить изменения"
MODULES_ERR_AL_SAVE = "Ошибка при сохранении"
MODULES_LEGEND = "Значения пиктограмм"
MODULES_AUTHOR = "Автор модуля"
MODULES_ERROR = "Возникла ошибка при загрузке модуля: "
@@ -39,10 +43,10 @@ MODULES_ERR_DUPLICATE_URL = "ВНИМАНИЕ: Данный ЧПУ адрес
MODULES_ERR_DUPLICATE_LINK = "ОШИБКА: Для этой оригинальной ссылки уже создан алиас. Дубликаты запрещены!"
MODULES_ERR_SAVE_FAILED = "Не удалось сохранить данные из-за ошибки в базе данных."
MODULES_EDIT_ALIAS = "Редактирование алиасов"
MODULES_REDIRECT = "Управление редиректами &#8250; "
MODULES_REDIRECT = "Управление редиректом"
MODULES_MODULE_HIS = "Модуль:"
MODULES_SYSLINK_HIS = "Системная ссылка:"
MODULES_MAIN_ALIASE_HIS = "Основной алиас:"
MODULES_SYSLINK_HIS = "Системный URL:"
MODULES_MAIN_ALIASE_HIS = "Основной ЧПУ алиас:"
MODULES_REDIRECT_ACTIV_HIS = "Список редиректов"
MODULES_LIST_ALIAS_HIS = "Алиас редиректа"
MODULES_NAME_LINK_HIS = "ссылка"
@@ -64,4 +68,45 @@ MODULES_MES_INS_ADR = "Введите адрес!"
MODULES_MES_ADD_HIS = "Добавлено в историю"
MODULES_MES_ERR_SAVE_HIS = "Ошибка сохранения"
MODULES_MES_DEL_SEL_HIS = "Удалить этот редирект?"
MODULES_MES_DEL_ONE_OK = "Запись удалена"
MODULES_MES_DEL_ONE_OK = "Запись удалена"
MODULES_REDIRECT_PARAM = "Параметры редиректа"
MODULES_SYS_NAME = "Системное имя модуля:"
MODULES_LINK_NAME = "Название редиректа"
MODULES_SYS_ACTIONS = "Системный Action:"
MODULES_ORIGINAL_URL = "Системный URL"
MODULES_PREWIEW_URL = "Предпросмотр URL"
MODULES_MAIN_ALIAS = "Основной ЧПУ алиас:"
MODULES_USE_ALIAS_DOC = "Привязка к документу:"
MODULES_USE_ALIAS_DOC_NO = "-- Без привязки --"
MODULES_SEL_CATEG = "-- Выберите рубрику --"
MODULES_ADMIN_ACCESS = "Доступ в админпанель:"
MODULES_ADMIN_ACCESS_SEL = "выбрать, если используется в админпанели"
MODULES_TXT_LOAD = "Загрузка..."
MODULES_TXT_SAVE = "Сохранение..."
MODULES_JS_ADD_LINK = "...введите ссылку..."
MODULES_JS_OK_ALERT = "Изменения успешно сохранены"
MODULES_MES_EMPTY_FIELDS = "Заполните все обязательные поля!"
MODULES_ALIASES_MOD_LIST = "Список модулей c редиректами"
MODULES_ACTION_TITLE = "Действие"
MODULES_DOC_ID = "Документ (ID)"
MODULES_DOC_TITLE_M = "Док."
MODULES_LINK_PUB_ADM = "Меню"
MODULES_LINK_SITE_M = "Сайт"
MODULES_LINK_HIS_M = "История"
MODULES_LINK_EDIT_M = "Правка"
MODULES_ERR_404_DOC = "Документ не найден"
MODULES_USE_M_DOC_NO = "Без привязки"
MODULES_USE_ML_DOC_NO = "Привязка отсутствует"
MODULES_LINK_M_ADM = "Админка"
MODULES_LINK_M_PUB = "Паблик"
MODULES_GO_EDIT_DOC = "Перейти к редактированию документа"
MODULES_GO_LOOK_SITE = "Посмотреть на сайте"
MODULES_HIS_REDIR_M = "История редиректа"
MODULES_REDIR_EDIT_M = "Редактировать редирект"
MODULES_ICO_EDIT_M = "Редактировать"
MODULES_ICO_DELET_M = "Удалить алиас"
MODULES_LIST_URL_A = "Список ЧПУ алиасов пуст."
MODULES_BACK_LIST_MOD = "Вернуться к списку модулей"
MODULES_ADD_REDIR_NEW = "Создать редирект"
MODULES_DEL_SEL_ALIAC = "Удалить выбранные алиасы"
MODULES_COL_SEL_ALIAC = "шт."

View File

@@ -1,33 +1,42 @@
<div class="title"><h5>Управление ЧПУ всех модулей</h5></div>
<div class="title"><h5>{#MODULES_ALIASES#}</h5></div>
<div class="widget" style="margin-top: 0px;">
<div class="body">
{#MODULES_ALIASES_TITLE#}
</div>
</div>
<div class="breadCrumbHolder module">
<div class="breadCrumb module">
<ul>
<li class="firstB"><a href="index.php" title="{#MAIN_PAGE#}">{#MAIN_PAGE#}</a></li>
<li><a href="index.php?do=modules&cp={$sess}">Управление модулями</a></li>
<li>Список всех ЧПУ</li>
<li><a href="index.php?do=modules&cp={$sess}">{#MODULES_SUB_TITLE#}</a></li>
<li>{#MODULES_ALIASES#}</li>
</ul>
</div>
</div>
<form action="index.php?do=modules&action=alias_delete_batch&cp={$sess}" method="post" id="AliasBatchForm" class="mainForm">
<div class="widget first">
<div class="head">
<h5 class="iFrames">{#MODULES_ALIASES_MOD_LIST#}</h5>
</div>
<table cellpadding="0" cellspacing="0" width="100%" class="tableStatic">
<thead>
<tr>
<td width="20"><div align="center"><input type="checkbox" class="selall_aliases"></div></td>
<td>Название ссылки</td>
<td>Системное имя</td>
<td>Action</td>
<td>Оригинальный URL</td>
<td>ЧПУ Алиас</td>
<td>Документ (ID)</td>
<td width="40" align="center">Меню</td>
<td width="40" align="center">Док.</td>
<td width="40" align="center">Сайт</td>
<td width="40" align="center">История</td>
<td width="40" align="center">Правка</td>
<td width="40" align="center">Удалить</td>
<td>{#MODULES_LINK_NAME#}</td>
<td>{#MODULES_SYS_NAME#}</td>
<td>{#MODULES_ACTION_TITLE#}</td>
<td>{#MODULES_ORIGINAL_URL#}</td>
<td>{#MODULES_MAIN_ALIAS#}</td>
<td>{#MODULES_DOC_ID#}</td>
<td width="40" align="center">{#MODULES_LINK_PUB_ADM#}</td>
<td width="40" align="center">{#MODULES_DOC_TITLE_M#}</td>
<td width="40" align="center">{#MODULES_LINK_SITE_M#}</td>
<td width="40" align="center">{#MODULES_LINK_HIS_M#}</td>
<td width="40" align="center">{#MODULES_LINK_EDIT_M#}</td>
<td width="40" align="center">{#MODULES_DEL_LINK_HIS#}</td>
</tr>
</thead>
<tbody>
@@ -46,36 +55,36 @@
<td>
{if $mod.doc_id > 0}
<span class="green" style="font-size: 11px;">
{$all_docs[$mod.doc_id]|default:'Документ не найден'}
{$all_docs[$mod.doc_id]|default:'{#MODULES_ERR_404_DOC#}'}
<small class="dgrey">(ID: {$mod.doc_id})</small>
</span>
{else}
<span class="dgrey">Без привязки</span>
<span class="dgrey">{#MODULES_USE_M_DOC_NO#}</span>
{/if}
</td>
<td align="center">
{if $mod.module_admin == '1'}
<span class="icon_sprite ico_navigation" title="В меню"></span>
<span class="icon_sprite ico_navigation topDir" title="{#MODULES_LINK_M_ADM#}"></span>
{else}
<span class="icon_sprite ico_navigation_no" title="Скрыт"></span>
<span class="icon_sprite ico_navigation_no topDir" title="{#MODULES_LINK_M_PUB#}"></span>
{/if}
</td>
<td align="center">
{if $mod.doc_id > 0 && $mod.rubric_id}
<a class="topDir icon_sprite ico_copy"
title="Перейти к редактированию документа"
<a class="topDir icon_sprite ico_copy topDir"
title="{#MODULES_GO_EDIT_DOC#}"
href="index.php?do=docs&action=edit&rubric_id={$mod.rubric_id}&Id={$mod.doc_id}&cp={$sess}"
target="_blank"></a>
{else}
<span class="icon_sprite ico_copy" style="opacity: 0.2;" title="Привязка отсутствует"></span>
<span class="icon_sprite ico_copy topDir" style="opacity: 0.2;" title="{#MODULES_USE_ML_DOC_NO#}"></span>
{/if}
</td>
<td align="center">
<a href="../{$mod.alias_url}"
title="Посмотреть на сайте"
title="{#MODULES_GO_LOOK_SITE#}"
class="icon_sprite ico_globus topDir"
target="_blank"></a>
</td>
@@ -85,9 +94,9 @@
data-dialog="alias-history-{$mod.id}"
data-height="650"
data-modal="true"
data-title="История алиасов модуля {$mod.sys_name}"
data-title="{#MODULES_HIS_REDIR_M#}"
class="openDialog icon_sprite ico_list topleftDir"
title="История"></a>
title="{#MODULES_LINK_HIS_M#}"></a>
</td>
<td align="center">
@@ -95,16 +104,16 @@
data-dialog="aliases-{$mod.id}"
data-height="650"
data-modal="true"
data-title="Редактировать алиас: {$mod.module_link_name|default:$mod.title}"
data-title="{#MODULES_REDIR_EDIT_M#}"
class="openDialog icon_sprite ico_edit topleftDir"
title="Редактировать"></a>
title="{#MODULES_ICO_EDIT_M#}"></a>
</td>
<td align="center">
<a href="javascript:void(0);"
class="icon_sprite ico_delete topleftDir"
title="Удалить"
onclick="jConfirm('Удалить алиас <strong>{$mod.alias_url}</strong>?', 'Подтверждение', function(r) {
title="{#MODULES_DEL_LINK_HIS#}"
onclick="jConfirm('{#MODULES_ICO_DELET_M#} <strong>{$mod.alias_url}</strong>?', '{#MODULES_MES_DEL_CONFRM_HIS#}', function(r) {
if(r) window.location.href='index.php?do=modules&action=alias_delete&id={$mod.id}&cp={$sess}';
});"></a>
</td>
@@ -113,7 +122,7 @@
<tr class="noborder">
<td colspan="13" align="center">
<ul class="messages">
<li class="highlight yellow">Список ЧПУ алиасов пуст.</li>
<li class="highlight yellow">{#MODULES_LIST_URL_A#}</li>
</ul>
</td>
</tr>
@@ -129,7 +138,7 @@
<tr>
<td colspan="13" style="padding: 10px;">
<div class="formSubmit" style="margin: 0; padding: 0; float: left;">
<input type="button" class="button redBtn deleteSelected" value="Удалить выбранные" style="float: left;">
<input type="button" class="button redBtn deleteSelected" value="{#MODULES_BTN_DEL_HIS#}" style="float: left;">
</div>
</td>
</tr>
@@ -140,14 +149,14 @@
</form>
<div class="fix" style="margin-top: 20px;">
<a href="index.php?do=modules&cp={$sess}" class="button basicBtn">Вернуться к списку модулей</a>
<a href="index.php?do=modules&cp={$sess}" class="button basicBtn">{#MODULES_BACK_LIST_MOD#}</a>
&nbsp;
<a href="index.php?do=modules&action=aliases&id=0&cp={$sess}&ajax=1&onlycontent=1"
data-dialog="aliases-0"
data-height="650"
data-modal="true"
data-title="Добавить новый алиас"
class="button basicBtn greenBtn openDialog">Добавить новый алиас</a>
data-title="{#MODULES_ADD_REDIR_NEW#}"
class="button basicBtn greenBtn openDialog">{#MODULES_ADD_REDIR_NEW#}</a>
</div>
{literal}
@@ -157,7 +166,7 @@ $(function() {
$('.selall_aliases').on('change', function() {
var checked = $(this).is(':checked');
$('.alias_check').prop('checked', checked);
// Обновляем визуальные стили jqTransform если используется
// Обновляем визуальные стили jqTransform
if ($.isFunction($.fn.jqTransform)) {
if(checked) {
$('.alias_check').parent().find('a').addClass('jqTransformChecked');
@@ -173,11 +182,11 @@ $(function() {
var $checked = $('.alias_check:checked');
if ($checked.length === 0) {
$.jGrowl("Ничего не выбрано!", {theme: 'error'});
$.jGrowl("{/literal}{#MODULES_MES_NO_SELECT_HIS#}{literal}!", {theme: 'error'});
return false;
}
jConfirm('Удалить выбранные алиасы (' + $checked.length + ' шт.)?', 'Подтверждение', function(r) {
jConfirm('{/literal}{#MODULES_DEL_SEL_ALIAC#}{literal} (' + $checked.length + ' {/literal}{#MODULES_COL_SEL_ALIAC#}{literal})?', '{/literal}{#MODULES_MES_DEL_CONFRM_HIS#}{literal}', function(r) {
if (r) {
$('#AliasBatchForm').submit();
}

View File

@@ -1,68 +1,88 @@
<div class="title">
<h5>Управление редиректами модуля <span class="blue">{$module_link_name}</span></h5>
<h5>{#MODULES_REDIRECT#} {$alias_data.module_link_name|default:''}</h5>
</div>
<div class="breadCrumbHolder module">
<div class="breadCrumb module">
<ul>
<li>Модуль: <strong class="code">{$alias_data.module_name|default:''}</strong></li>
<li>Системная ссылка: <strong class="code">{$alias_data.module_link|default:''}</strong></li>
<li>Основной алиас: <strong class="code">{$alias_data.module_url|default:''}</strong></li>
<li>{#MODULES_MODULE_HIS#} <strong class="code">{$alias_data.module_name|default:''}</strong></li>
<li>{#MODULES_SYSLINK_HIS#} <strong class="code">{$alias_data.module_link|default:''}</strong></li>
<li>{#MODULES_MAIN_ALIASE_HIS#} <strong class="code">{$alias_data.module_url|default:''}</strong></li>
</ul>
</div>
</div>
<div class="widget first">
<div class="head">
<h5 class="iPlus">Параметры редиректа</h5>
<div class="head">
<h5 class="iPlus">{#MODULES_REDIRECT_PARAM#}</h5>
</div>
<form action="index.php?do=modules&action=aliases&id={$alias_id}&cp={$sess}&ajax=1&onlycontent=1" method="post" id="AliasForm">
<input type="hidden" name="save_aliases" value="1" />
<table cellpadding="0" cellspacing="0" width="100%" class="tableStatic mainForm">
<tr>
<td width="150">Системное имя модуля:</td>
<td><input type="text" name="module_name" value="{$alias_data.module_name|default:''}" style="width: 95%;" placeholder="Например: search" /></td>
<td width="150">{#MODULES_SYS_NAME#}</td>
<td><input type="text" name="module_name" value="{$alias_data.module_name|default:''}" style="width: 95%;" /></td>
</tr>
<tr>
<td width="150">Название ссылки:</td>
<td width="150">{#MODULES_LINK_NAME#}:</td>
<td><input type="text" name="module_link_name" value="{$alias_data.module_link_name|default:''}" style="width: 95%;" /></td>
</tr>
<tr>
<td>Системный Action:</td>
<td>{#MODULES_SYS_ACTIONS#}</td>
<td><input type="text" name="module_action" value="{$alias_data.module_action|default:''}" style="width: 95%;" /></td>
</tr>
<tr>
<td>Оригинальный URL:</td>
<td><input type="text" name="module_link" value="{$alias_data.module_link|default:''}" style="width: 95%;" /></td>
<td>
<div style="display: flex; align-items: center; gap: 8px;">{#MODULES_ORIGINAL_URL#}<a href="javascript:void(0);" id="toggle_preview_ui" class="icon_sprite ico_look topDir" title="{#MODULES_PREWIEW_URL#}" style="cursor: pointer;"></a></div>
</td>
<td>
<div style="display: flex; align-items: center; gap: 8px;">
<input type="text" name="module_link" value="{$alias_data.module_link|default:''}" style="width: 95%;" />
</div>
<div id="url_preview_box" style="margin-top: 8px; padding: 8px 10px; background: #fdfdfd; border: 1px solid #e0e0e0; font-family: 'Courier New', monospace; font-size: 11px; color: #555; word-break: break-all; border-radius: 3px; display: none; width: 93%;">
<span id="url_res_path" style="color: #999;">{if $smarty.const.ABS_PATH|substr:0:4 == 'http'}{$smarty.const.ABS_PATH}{else}{$smarty.server.REQUEST_SCHEME}://{$smarty.server.HTTP_HOST}{$smarty.const.ABS_PATH}{/if}</span><span id="url_res_link" style="font-weight: bold; color: #2c3e50;"></span>
</div>
</td>
</tr>
<tr>
<td><strong>ЧПУ Алиас:</strong></td>
<td><strong>{#MODULES_MAIN_ALIAS#}</strong></td>
<td><input type="text" name="module_url" value="{$alias_data.module_url|default:''}" style="width: 95%; font-weight: bold;" /></td>
</tr>
<tr>
<td>Привязка к документу:</td>
<td>{#MODULES_USE_ALIAS_DOC#}</td>
<td>
<select name="document_id" style="width: 98%;">
<option value="0">-- Без привязки --</option>
{foreach from=$all_docs key=d_id item=d_title}
<option value="{$d_id}" {if $d_id == ($alias_data.document_id|default:0)}selected="selected"{/if}>{$d_title}</option>
{/foreach}
</select>
<div style="display: flex; gap: 10px; align-items: center; width: 98%;">
<select id="rubric_selector" style="width: 45%;">
<option value="0">{#MODULES_SEL_CATEG#}</option>
{foreach from=$all_rubrics key=r_id item=r_title}
<option value="{$r_id}" {if $r_id == $current_rubric_id}selected="selected"{/if}>{$r_title}</option>
{/foreach}
</select>
<select name="document_id" id="document_selector" style="width: 55%;">
<option value="0">{#MODULES_USE_ALIAS_DOC_NO#}</option>
{foreach from=$all_docs key=d_id item=d_title}
<option value="{$d_id}" {if $d_id == ($alias_data.document_id|default:0)}selected="selected"{/if}>{$d_title}</option>
{/foreach}
</select>
</div>
</td>
</tr>
<tr>
<td>Доступ в админке:</td>
<td>{#MODULES_ADMIN_ACCESS#}</td>
<td style="vertical-align: middle;">
<div style="display: flex; align-items: center; gap: 8px; min-height: 24px;">
<input type="checkbox" name="module_admin" value="1" class="checkbox" {if $alias_id != 0 && ($alias_data.module_admin|default:'0') == '1'}checked="checked"{/if}} />
<label style="margin: 0; cursor: pointer; white-space: nowrap; line-height: 1;">Отображать в меню модулей</label>
<input type="checkbox" name="module_admin" value="1" class="checkbox" {if $alias_id != 0 && ($alias_data.module_admin|default:'0') == '1'}checked="checked"{/if} />
<label style="margin: 0; cursor: pointer; white-space: nowrap; line-height: 1;">{#MODULES_ADMIN_ACCESS_SEL#}</label>
</div>
</td>
</td>
</tr>
<tr>
<td colspan="2" style="padding: 15px 10px;">
<input type="submit" class="basicBtn SaveAlias" value="Сохранить изменения" />
<input type="submit" class="basicBtn SaveAlias" value="{#MODULES_BUTTON_SAVE#}" />
&nbsp;
<a href="javascript:void(0);" class="button redBtn CloseModal">Закрыть окно</a>
<a href="javascript:void(0);" class="button redBtn CloseModal">{#MODULES_BTN_CLOSE_WIN_HIS#}</a>
</td>
</tr>
</table>
@@ -74,16 +94,118 @@
$(function(){
var a_id = '{/literal}{$alias_id}{literal}';
// Инициализация плагинов
$("#AliasForm").jqTransform();
setTimeout(function() {
$('#AliasForm select').styler({
selectSmartPositioning: true,
selectVisibleOptions: 5,
selectSearch: false
$('#AliasForm select').styler({
selectSmartPositioning: true,
selectVisibleOptions: 5,
selectSearch: false
});
}, 100);
// --- Рубрика -> Документ ---
$('#rubric_selector').on('change', function() {
var rubricId = $(this).val();
var $docSelect = $('#document_selector');
$docSelect.html('<option value="0">{/literal}{#MODULES_TXT_LOAD#}{literal}</option>');
if ($.fn.styler) $docSelect.trigger('refresh');
if (parseInt(rubricId) === 0) {
$docSelect.html('<option value="0">{/literal}{#MODULES_USE_ALIAS_DOC_NO#}{literal}</option>');
if ($.fn.styler) $docSelect.trigger('refresh');
return;
}
$.getJSON('index.php?do=modules&action=aliases&id=' + a_id + '&get_docs_by_rubric=1&rubric_id=' + rubricId, function(data) {
var options = '<option value="0">{/literal}{#MODULES_USE_ALIAS_DOC_NO#}{literal}</option>';
$.each(data, function(i, item) {
options += '<option value="' + item.Id + '">' + item.document_title + '</option>';
});
$docSelect.html(options);
if ($.fn.styler) $docSelect.trigger('refresh');
});
});
// --- предпросмотр ссылки ---
var $linkInput = $('input[name="module_link"]');
var $adminCheck = $('input[name="module_admin"]');
var $preview = $('#url_res_link');
var $previewBox = $('#url_preview_box');
var $toggleUi = $('#toggle_preview_ui');
var storageKey = 'cms_alias_preview_visible';
var isVisible = localStorage.getItem(storageKey) === 'true';
if (isVisible) {
$previewBox.show();
$toggleUi.css('opacity', '1');
} else {
$toggleUi.css('opacity', '0.5');
}
$toggleUi.on('click', function(e) {
e.preventDefault();
$previewBox.stop().slideToggle(200, function() {
var nowVisible = $previewBox.is(':visible');
localStorage.setItem(storageKey, nowVisible);
$toggleUi.css('opacity', nowVisible ? '1' : '0.5');
});
});
function cleanUrl(val) {
if (!val) return '';
var clean = val.trim().replace(/\s/g, '');
clean = clean.replace(/^https?:\/\/[^\/]+/i, '');
clean = clean.replace(/([\?&])cp=[^&]*/gi, '');
clean = clean.replace(/^\/+/, '').replace(/[\?&]$/, '');
return clean;
}
function updateUrlPreview() {
var rawValue = $linkInput.val();
var link = cleanUrl(rawValue);
var isAdmin = $adminCheck.is(':checked');
if (link === '') {
$preview.html('<span style="color:#ccc;">{/literal}{#MODULES_JS_ADD_LINK#}{literal}</span>');
return;
}
var prefix = '';
var sessionPart = '';
if (isAdmin) {
if (!link.toLowerCase().startsWith('admin/')) {
prefix = '<span style="color: #27ae60;">admin/</span>';
}
var connector = link.indexOf('?') !== -1 ? '&' : '?';
sessionPart = '<span style="color: #27ae60;">' + connector + 'cp=SESSION_ID</span>';
} else {
if (link.toLowerCase().startsWith('admin/')) {
link = link.substring(6);
}
}
$preview.html(prefix + link + sessionPart);
var cleanedRaw = cleanUrl(rawValue);
if (rawValue !== cleanedRaw && rawValue.indexOf('://') !== -1) {
$linkInput.val(cleanedRaw);
}
}
$linkInput.on('keyup input paste', function() {
setTimeout(updateUrlPreview, 10);
});
}, 100);
$adminCheck.on('change', function() {
setTimeout(updateUrlPreview, 50);
});
updateUrlPreview();
function closeAndReload() {
$('#ajax-dialog-aliases-' + a_id).dialog('destroy').remove();
if (window.parent) window.parent.location.reload();
@@ -100,18 +222,29 @@ $(function(){
if (window.parent) window.parent.location.reload();
});
$(document).off('click', '.SaveAlias').on('click', '.SaveAlias', function(e){
$(document).off('click', '.SaveAlias').on('click', '.SaveAlias', function(e){
e.preventDefault();
var $btn = $(this);
$("#AliasForm").ajaxSubmit({
var $form = $("#AliasForm");
var moduleName = $form.find('input[name="module_name"]').val().trim();
var moduleLink = $form.find('input[name="module_link"]').val().trim();
var moduleUrl = $form.find('input[name="module_url"]').val().trim();
if (moduleName === '' || moduleLink === '' || moduleUrl === '') {
var errorMsg = "{/literal}{#MODULES_MES_EMPTY_FIELDS#}{literal}";
$.jGrowl(errorMsg, { theme: 'error' });
return false;
}
$form.ajaxSubmit({
dataType: 'json',
beforeSubmit: function() {
$btn.attr("disabled", true).val("Сохранение...");
$btn.attr("disabled", true).val("{/literal}{#MODULES_TXT_SAVE#}{literal}");
},
success: function(r){
if (r && r.status == 'success') {
$.jGrowl(r.message || "Изменения успешно сохранены", {
$.jGrowl(r.message || "{/literal}{#MODULES_JS_OK_ALERT#}{literal}", {
theme: "accept",
life: 3000
});
@@ -121,20 +254,20 @@ $(function(){
if (window.parent) window.parent.location.reload();
}, 900);
} else {
$btn.attr("disabled", false).val("Сохранить изменения");
$btn.attr("disabled", false).val("{/literal}{#MODULES_BUTTON_SAVE#}{literal}");
}
} else {
var msg = (r && r.message) ? r.message : "Ошибка при сохранении";
var msg = (r && r.message) ? r.message : "{/literal}{#MODULES_ERR_AL_SAVE#}{literal}";
$.jGrowl(msg, {
theme: "error",
life: 5000
});
$btn.attr("disabled", false).val("Сохранить изменения");
$btn.attr("disabled", false).val("{/literal}{#MODULES_BUTTON_SAVE#}{literal}");
}
},
error: function() {
$.jGrowl("Критическая ошибка сервера", { theme: "error" });
$btn.attr("disabled", false).val("Сохранить изменения");
$btn.attr("disabled", false).val("{/literal}{#MODULES_BUTTON_SAVE#}{literal}");
}
});
});

View File

@@ -1967,7 +1967,8 @@
document_id,
module_name,
module_action,
module_link
module_link,
module_admin
FROM
" . PREFIX . "_modules_aliases
WHERE
@@ -1980,6 +1981,35 @@
//-- Если модуль есть, переназначаем URL и переменные
if ($module)
{
// --- ПРОВЕРКА ДЛЯ АЛИАСА МОДУЛЯ ИСПОЛЬЗУЮЩЕГО АДМИНКУ ---
$is_admin_group = (isset($_SESSION['user_group']) && $_SESSION['user_group'] == 1);
$has_admin_rights = (isset($_SESSION['alles']) && $_SESSION['alles'] == 1) || (isset($_SESSION['adminpanel']) && $_SESSION['adminpanel'] == 1);
if (isset($module['module_admin']) && $module['module_admin'] == 1 && ($is_admin_group || $has_admin_rights))
{
$target_link = ltrim($module['module_link'], '/');
// Проверяем, есть ли уже префикс admin/
$has_admin_prefix = preg_match('/^admin\//i', $target_link);
// Если галочка стоит, а префикса нет — добавляем его
if (!$has_admin_prefix) {
$target_link = 'admin/' . $target_link;
}
// Формируем токен и финальную ссылку
// Пытаемся взять токен из сессии, если его нет — генерируем через ID сессии
$session_token = isset($_SESSION['cp']) ? $_SESSION['cp'] : session_id();
$connector = (strpos($target_link, '?') === false) ? '?' : '&';
$admin_jump = ABS_PATH . $target_link . $connector . 'cp=' . $session_token;
if (ob_get_length()) ob_clean();
header('Location: ' . $admin_jump);
exit;
}
// --- END ПРОВЕРКА ДЛЯ АЛИАСА МОДУЛЯ В АДМИНКУ ---
//-- Передаем глобальные перемененные
$_GET['module'] = $_REQUEST['module'] = $module['module_name'];
$_GET['action'] = $_REQUEST['action'] = $module['module_action'];

View File

@@ -683,6 +683,14 @@ public function moduleAliasSave($id, $data)
global $AVE_DB;
$id = (int)$id;
// проверка на пустоту обязательных полей
if (empty(trim($data['module_name'] ?? '')) ||
empty(trim($data['module_link'] ?? '')) ||
empty(trim($data['module_url'] ?? '')))
{
return 'error_empty_fields';
}
$module_name = addslashes($data['module_name'] ?? '');
$module_link_name = addslashes($data['module_link_name'] ?? '');
$module_action = addslashes($data['module_action'] ?? '');
@@ -691,6 +699,40 @@ public function moduleAliasSave($id, $data)
$document_id = (int)($data['document_id'] ?? 0);
$module_admin = (int)($data['module_admin'] ?? 0);
// --- ОЧИСТКА module_link ---
$module_link = trim($data['module_link'] ?? '');
if (!empty($module_link))
{
// Убираем протокол
$module_link = preg_replace('/^https?:\/\//i', '', $module_link);
// Если в строке есть домен (точка + слеш), отрезаем только доменную часть
// Пример: домен.ru/index.php?a=1 -> index.php?a=1
if (preg_match('/^[a-z0-9-]+\.[a-z]{2,6}\//i', $module_link))
{
$module_link = substr($module_link, strpos($module_link, '/') + 1);
}
// Если ввели ТОЛЬКО домен без слеша (напр. домен.ru)
// проверяем, нет ли в строке точки и отсутствуют ли при этом слеши
elseif (preg_match('/^[a-z0-9-]+\.[a-z]{2,6}$/i', $module_link))
{
$module_link = 'index.php';
}
// убираем лишние слеши только с краев
$module_link = trim($module_link, '/ ');
// Если совсем пусто — ставим заглушку
if (empty($module_link)) $module_link = 'index.php';
}
else
{
$module_link = 'index.php';
}
$module_link = addslashes($module_link);
// --- END ОЧИСТКА ---
$exact_match = $AVE_DB->Query("SELECT id FROM " . PREFIX . "_modules_aliases
WHERE id = '{$id}'
AND module_name = '{$module_name}'
@@ -849,7 +891,7 @@ public function deleteAliasHistory($h_id)
}
/**
* Метод для отображения списка всех алиасов с поддержкой навигации по документам
* Метод для отображения списка всех алиасов
*/
public function getAliasesAll()
{
@@ -905,6 +947,20 @@ public function getAliasEdit($alias_id)
global $AVE_DB, $AVE_Template;
$alias_id = (int)$alias_id;
if (isset($_GET['get_docs_by_rubric'])) {
$rubric_id = (int)$_GET['rubric_id'];
$docs = [];
$sql = "SELECT Id, document_title FROM " . PREFIX . "_documents
WHERE rubric_id = '{$rubric_id}'
ORDER BY document_title ASC";
$q = $AVE_DB->Query($sql);
while ($d = $q->FetchAssocArray()) {
$docs[] = $d;
}
echo json_encode($docs);
exit;
}
$alias_data = $AVE_DB->Query("SELECT * FROM " . PREFIX . "_modules_aliases WHERE id = '{$alias_id}'")->FetchAssocArray();
if (!$alias_data) {
$alias_data = [
@@ -913,17 +969,33 @@ public function getAliasEdit($alias_id)
];
}
$all_docs = array();
$doc_q = $AVE_DB->Query("SELECT Id, document_title FROM " . PREFIX . "_documents ORDER BY document_title ASC");
while ($d = $doc_q->FetchAssocArray()) {
$all_docs[$d['Id']] = $d['document_title'];
$current_rubric_id = 0;
if ($alias_data['document_id'] > 0) {
$doc_info = $AVE_DB->Query("SELECT rubric_id FROM " . PREFIX . "_documents WHERE Id = '{$alias_data['document_id']}' LIMIT 1")->FetchAssocArray();
$current_rubric_id = $doc_info['rubric_id'] ?? 0;
}
$all_rubrics = [];
$rub_q = $AVE_DB->Query("SELECT Id, rubric_title FROM " . PREFIX . "_rubrics ORDER BY rubric_title ASC");
while ($r = $rub_q->FetchAssocArray()) {
$all_rubrics[$r['Id']] = $r['rubric_title'];
}
$all_docs = [];
if ($current_rubric_id > 0) {
$doc_q = $AVE_DB->Query("SELECT Id, document_title FROM " . PREFIX . "_documents WHERE rubric_id = '{$current_rubric_id}' ORDER BY document_title ASC");
while ($d = $doc_q->FetchAssocArray()) {
$all_docs[$d['Id']] = $d['document_title'];
}
}
$AVE_Template->assign([
'alias_id' => $alias_id,
'alias_data' => $alias_data,
'all_docs' => $all_docs,
'sess' => SESSION
'alias_id' => $alias_id,
'alias_data' => $alias_data,
'all_rubrics' => $all_rubrics,
'current_rubric_id' => $current_rubric_id,
'all_docs' => $all_docs,
'sess' => SESSION
]);
if (isset($_REQUEST['ajax']) || isset($_REQUEST['onlycontent'])) {

View File

@@ -370,7 +370,4 @@ INSERT INTO `%%PRFX%%_users`
INSERT INTO `%%PRFX%%_paginations` (`id`, `pagination_name`, `pagination_box`, `pagination_start_label`, `pagination_end_label`, `pagination_separator_box`, `pagination_separator_label`, `pagination_next_label`, `pagination_prev_label`, `pagination_link_box`, `pagination_active_link_box`, `pagination_link_template`, `pagination_link_active_template`)
VALUES
(1, 'Общий шаблон', '<ul class=\"pagination pagination-sm\">%s</ul>', '<span aria-hidden=\"true\">Первая</span>', '<span aria-hidden=\"true\">Последняя</span>', '<li class=\"disabled\"><span aria-hidden=\"true\">%s</span></li>', '', '<i class=\"bi bi-arrow-right\"></i>', '<i class=\"bi bi-arrow-left\"></i>', '<li class=\"page-item\">%s</li>', '<li class=\"page-item active\">%s</li>', '<a class=\"page-link\" href=\"[link]\" data-pagination=\"[page]\">[name]</a>', '<a class=\"page-link active\" href=\"[link]\">[name]</a>');#inst#
-- Пример алиаса для модуля Поиск
INSERT INTO `%%PRFX%%_modules_aliases` (`id`, `document_id`, `module_name`, `module_action`, `module_link`, `module_link_name`, `module_url`, `module_admin`) VALUES
(1, 0, 'search', 'search', 'index.php?module=search&query=', 'Поиск по сайту', 'search/', '0');#inst#
(1, 'Общий шаблон', '<ul class=\"pagination pagination-sm\">%s</ul>', '<span aria-hidden=\"true\">Первая</span>', '<span aria-hidden=\"true\">Последняя</span>', '<li class=\"disabled\"><span aria-hidden=\"true\">%s</span></li>', '', '<i class=\"bi bi-arrow-right\"></i>', '<i class=\"bi bi-arrow-left\"></i>', '<li class=\"page-item\">%s</li>', '<li class=\"page-item active\">%s</li>', '<a class=\"page-link\" href=\"[link]\" data-pagination=\"[page]\">[name]</a>', '<a class=\"page-link active\" href=\"[link]\">[name]</a>');#inst#