Файл admin.structure.php в Cotonti CMF
предназначен для управления структурой (категориями) в системе, реализует интерфейс администратора для добавления, изменения, удаления и настройки категорий, используемых в модулях или плагинах
Основное назначение файла "admin.structure.php" и его место в системе
Файл admin.structure.php предназначен для управления структурой (категориями) в системе Cotonti CMF. Он реализует интерфейс администратора для добавления, изменения, удаления и настройки категорий, используемых в модулях или плагинах. Это ключевая часть административной панели для управления иерархией категорий, включая их дополнительные поля, права доступа, шаблоны и настройки.
Место в системе:
- Входит в административный модуль.
- Используется для работы с таблицей
cot_structureв базе данных. - Обеспечивает динамическую генерацию интерфейса на основе данных, хранящихся в структуре.
Основные задачи и условия, выполняемые в коде
-
Отображение текущей структуры категорий:
- Подгрузка категорий из базы данных.
- Визуализация их иерархии (уровень вложенности, пути).
-
Добавление новых категорий:
- Обработка формы для создания новой категории.
- Указание пути, заголовка, описания, значков и других параметров.
-
Редактирование существующих категорий:
- Обработка входных данных для обновления информации о категории (код, название, описание и т.д.).
- Настройка шаблонов для категорий (включая выбор дочерних шаблонов).
-
Удаление категорий:
- Проверка возможности удаления категории (например, отсутствие вложенных объектов).
- Удаление категории из базы данных.
-
Работа с дополнительными полями (extra fields):
- Поддержка произвольных полей, созданных администраторами через API Cotonti.
-
Взаимодействие с правами доступа:
- Генерация ссылок для настройки прав доступа для каждой категории.
-
Реализация пагинации:
- Поддержка навигации при большом количестве категорий.
-
Обработка AJAX-запросов:
- Удаление и обновление категорий с использованием AJAX.
Список функций, используемых в файле
1. cot_url()
Назначение: Генерирует URL для административного интерфейса.
Что делает:
- Собирает параметры в GET-запрос.
- Возвращает корректный путь на основе роутера Cotonti.
2. cot_import()
Назначение: Импортирует данные из внешнего источника (GET, POST, COOKIE).
Что делает:
- Проверяет входные данные на корректность (строки, числа и т.д.).
- Возвращает значение или
null, если данные отсутствуют.
3. cot_check_xg()
Назначение: Проверяет CSRF-токен.
Что делает:
- Защищает от межсайтовых запросов с поддельными токенами.
- Возвращает
true, если токен валиден.
4. cot_confirm_url()
Назначение: Создает ссылку с подтверждением действия.
Что делает:
- Генерирует URL, включающий уникальный ключ защиты (CSRF).
5. cot_selectbox()
Назначение: Создает HTML-элемент <select> с опциями.
Что делает:
- Принимает массивы значений и отображаемых текстов.
- Возвращает HTML-код выпадающего списка.
6. cot_checkbox()
Назначение: Создает HTML-элемент <input type="checkbox">.
Что делает:
- Возвращает чекбокс с заданными атрибутами.
7. cot_inputbox()
Назначение: Генерирует HTML-элемент <input> для текстовых полей.
Что делает:
- Поддерживает указание атрибутов (maxlength, placeholder и т.д.).
8. cot_build_extrafields()
Назначение: Генерирует HTML-элемент для работы с дополнительными полями (extra fields).
Что делает:
- Определяет тип поля (текст, дата, файл).
- Возвращает HTML-код для вывода в шаблоне.
9. cot_structure_children()
Назначение: Возвращает массив дочерних элементов категории.
Что делает:
- Определяет вложенные категории.
- Может возвращать только непосредственных детей или всех потомков.
10. cot_display_messages()
Назначение: Отображает уведомления для пользователя.
Что делает:
- Обрабатывает сообщения, добавленные через
cot_message(). - Генерирует HTML-код уведомлений.
Список методов и их назначение
Методов, как таковых, в данном файле нет. Используются функции процедурного стиля.
Взаимодействие с классами
-
Cot::$db- Как взаимодействует: Обеспечивает доступ к объекту базы данных.
- Используется для: Выполнения SQL-запросов (
SELECT,INSERT,UPDATE,DELETE).
-
Cot::$cfg- Как взаимодействует: Содержит глобальные настройки системы.
- Используется для: Проверки конфигурации (например, активация режима совместимости).
-
Cot::$L- Как взаимодействует: Локализация интерфейса.
- Используется для: Вывода строк с текстами из языкового файла.
-
Cot::$sys- Как взаимодействует: Доступ к системным параметрам (время, CSRF-токен и т.д.).
- Используется для: Вставки ключей защиты в формы и ссылки.
Взаимодействие с объектами
-
Объект базы данных (
Cot::$db)- Выполняются запросы на выборку, обновление и удаление данных.
-
Шаблонизатор (
$t)- Как взаимодействует: Передает данные из PHP-кода в шаблон.
- Используется для: Генерации HTML на основе заданного шаблона.
-
Сессия (
$_SESSION)- Как взаимодействует: Используется для хранения временных данных (например, буфера изменений).
-
Объект структуры (
$row)- Представляет собой запись в таблице структуры.
- Используется для обработки данных о категориях.
Стиль PHP-кода
Код написан в процедурном стиле, характерном для более ранних версий PHP. Однако используются современные элементы:
- Глобальные классы (
Cot::$db,Cot::$cfg). - Псевдоним пространства имен (
Cot::$). - Четкое разделение логики на секции с использованием хуков.
Особенности стиля:
- Логика сосредоточена в основном в одном файле.
- Используются глобальные переменные и функции.
- Минимальное использование ООП.
находится по адресу: /system/admin/admin.structure.php движка php-фреймворка Cotonti.
<?php
/**
* Панель администратора
*
* @package Cotonti
* @copyright (c) Cotonti Team
* @license https://github.com/Cotonti/Cotonti/blob/master/License.txt
*
* @var string $n Код расширения
*/
(defined('COT_CODE') && defined('COT_ADMIN')) or die('Wrong URL.'); // Проверка, что скрипт вызывается в правильном контексте (COT_CODE и COT_ADMIN должны быть определены)
list(Cot::$usr['auth_read'], Cot::$usr['auth_write'], Cot::$usr['isadmin']) = cot_auth('admin', 'a'); // Получение прав доступа пользователя (чтение, запись, админ) для раздела 'admin'
cot_block(Cot::$usr['isadmin']); // Блокирует доступ, если у пользователя нет прав администратора
require_once cot_incfile('extrafields'); // Подключение файла с дополнительными полями
require_once cot_incfile('structure'); // Подключение файла с функциональностью для структуры
$id = cot_import('id', 'G', 'INT'); // Получение параметра 'id' из GET-запроса, ожидается целое число
$al = cot_import('al', 'G', 'ALP'); // Получение параметра 'al' из GET-запроса, ожидается строка (буквы)
$c = cot_import('c', 'G', 'TXT'); // Получение параметра 'c' из GET-запроса, ожидается текст
$v = cot_import('v', 'G', 'TXT'); // Получение параметра 'v' из GET-запроса, ожидается текст
$maxrowsperpage = (is_int(Cot::$cfg['maxrowsperpage']) && Cot::$cfg['maxrowsperpage'] > 0 || ctype_digit(Cot::$cfg['maxrowsperpage'])) ? // Проверка корректности настройки максимального количества строк на странице
Cot::$cfg['maxrowsperpage'] : 15; // Если настройка корректна, используется её значение, иначе по умолчанию 15
list($pg, $d, $durl) = cot_import_pagenav('d', $maxrowsperpage); // Получение параметров для пагинации: текущая страница, количество элементов на странице и ссылка для пагинации
$mode = cot_import('mode', 'G', 'ALP'); // Получение параметра 'mode' из GET-запроса, ожидается строка (буквы)
$t = new XTemplate(cot_tplfile(array('admin', 'structure', $n), 'core')); // Создание нового объекта XTemplate для загрузки шаблона, с учетом параметра $n (код расширения)
$adminTitle = Cot::$L['Structure']; // Установка заголовка для админки "Структура" из локализованных данных
$extensionsWithStructure = cot_getExtensionsWithStructure(); // Получение списка расширений, которые имеют структуру
$legacyMode = isset(Cot::$cfg['legacyMode']) && Cot::$cfg['legacyMode']; // Проверка, включен ли режим совместимости (legacyMode) в конфигурации
if ($legacyMode) { // Если режим совместимости включен
$extension_structure = []; // Инициализация пустого массива для структуры расширений в старом режиме
}
/* === Hook === */
foreach (cot_getextplugins('admin.structure.first') as $pl) { // Перебор всех плагинов для хука 'admin.structure.first'
include $pl; // Включение каждого плагина
}
/* ===== */
if ($legacyMode && !empty($extension_structure)) { // Если режим совместимости активен и структура расширений не пуста
$extensionsWithStructure = array_merge($extensionsWithStructure, $extension_structure); // Слияние структур расширений с основной структурой
unset($extension_structure); // Удаление временной переменной $extension_structure
}
if (empty($n)) { // Если параметр $n пустой (не указан код расширения)
$adminPath[] = [cot_url('admin', 'm=structure'), Cot::$L['Structure'],]; // Добавление пути в навигацию "Структура"
// Show available module list
if (
is_array($extensionsWithStructure) // Проверка, является ли $extensionsWithStructure массивом
&& count($extensionsWithStructure) == 1 // Если в массиве только один элемент
&& ((cot_plugin_active($extensionsWithStructure[0]) || cot_module_active($extensionsWithStructure[0]))) // Если это активное расширение или модуль
) {
cot_redirect(cot_url('admin', 'm=structure&n='.$extensionsWithStructure[0], '', true)); // Перенаправление на страницу этого расширения или модуля
}
if (is_array($extensionsWithStructure) && count($extensionsWithStructure) > 0) { // Если $extensionsWithStructure массив и в нем больше одного элемента
foreach ($extensionsWithStructure as $code) { // Перебор всех расширений с структурой
$parse = false; // Флаг для определения, нужно ли парсить расширение
if (cot_plugin_active($code)) { // Если плагин активен
$is_module = false; // Это не модуль
$parse = true; // Устанавливаем флаг на true для парсинга
}
if (cot_module_active($code)) { // Если модуль активен
$is_module = true; // Это модуль
$parse = true; // Устанавливаем флаг на true для парсинга
}
if ($parse) { // Если флаг парсинга установлен в true
$ext_info = cot_get_extensionparams($code, $is_module); // Получаем параметры расширения
$t->assign([
'ADMIN_STRUCTURE_EXT_URL' => cot_url('admin', 'm=structure&n='.$code), // Установка URL для расширения
'ADMIN_STRUCTURE_EXT_ICON' => $ext_info['icon'], // Установка иконки расширения
'ADMIN_STRUCTURE_EXT_NAME' => $ext_info['name'], // Установка имени расширения
'ADMIN_STRUCTURE_EXT_DESC' => $ext_info['desc'], // Установка описания расширения
]);
if (isset(Cot::$cfg['legacyMode']) && Cot::$cfg['legacyMode']) { // Если включен режим совместимости
$t->assign([
// @deprecated For backward compatibility. Will be removed in future releases
'ADMIN_STRUCTURE_EXT_ICO' => $ext_info['legacyIcon'], // Установка старой иконки для совместимости
]);
}
$t->parse('LIST.ADMIN_STRUCTURE_EXT'); // Парсинг расширения в шаблон
}
}
}
else
{
$t->parse('LIST.ADMIN_STRUCTURE_EMPTY'); // Если нет расширений, парсинг пустого списка
}
$t->assign(array(
'ADMIN_STRUCTURE_EXFLDS_URL' => cot_url('admin', 'm=extrafields') // Установка URL для экстра-полей
));
$t->parse('LIST'); // Парсинг списка расширений
$adminMain = $t->text('LIST'); // Получение и сохранение HTML-кода для основного контента
} else { // Если параметр $n не пустой (указан код расширения)
} else { // Если параметр $n не пустой (указан код расширения)
$parse = false; // Флаг для определения необходимости парсинга
if (!in_array($n, $extensionsWithStructure, true)) { // Если $n не найден в массиве расширений с структурой
cot_die_message(404); // Завершаем выполнение с ошибкой 404 (не найдено)
}
if (cot_plugin_active($n)) { // Если плагин активен
$is_module = false; // Это не модуль
$parse = true; // Устанавливаем флаг парсинга
}
if (cot_module_active($n)) { // Если модуль активен
$is_module = true; // Это модуль
$parse = true; // Устанавливаем флаг парсинга
}
if (!$parse) { // Если флаг парсинга не установлен
cot_redirect(cot_url('admin', 'm=structure', '', true)); // Перенаправляем на страницу структуры
}
// Edit structure for a module
if (file_exists(cot_incfile($n, $is_module ? 'module' : 'plug'))) { // Если существует файл для модуля или плагина
require_once cot_incfile($n, $is_module ? 'module' : 'plug'); // Подключаем файл модуля или плагина
}
if (empty($adminHelp)) { // Если переменная $adminHelp пуста
$adminHelp = Cot::$L['adm_help_structure']; // Устанавливаем помощь по структуре
}
if ($a == 'reset' && !empty($al)) { // Если параметр $a равен 'reset' и $al не пустой
cot_config_reset($n, $v, $is_module, $al); // Сброс конфигурации для расширения
}
if ($a == 'update' && !empty($_POST)) { // Если параметр $a равен 'update' и запрос не пустой
$editconfig = cot_import('editconfig', 'P', 'TXT'); // Импортируем параметр 'editconfig' из POST-запроса
if (!empty($editconfig)) { // Если параметр 'editconfig' не пустой
$owner = $is_module ? 'module' : 'plug'; // Определяем, является ли объект модулем или плагином
$optionslist = cot_config_list($owner, $n, $editconfig); // Получаем список опций конфигурации для расширения
foreach ($optionslist as $key => $val) { // Перебираем список опций
$data = cot_import($key, 'P', !empty($cot_import_filters[$key]) ? $key : 'NOC'); // Импортируем значение конфигурации
if ($optionslist[$key]['config_value'] != $data) { // Если новое значение отличается от текущего
if (!isset($optionslist[$key]['config_subdefault'])) { // Если опция не имеет подкатегории по умолчанию
$optionslist[$key]['config_value'] = $data; // Обновляем значение опции
$optionslist[$key]['config_subcat'] = $editconfig; // Устанавливаем подкатегорию
Cot::$db->insert($db_config, $optionslist[$key]); // Вставляем новую опцию в базу данных
} else {
Cot::$db->update( // Если подкатегория уже установлена, обновляем запись в базе данных
$db_config,
array('config_value' => $data), // Обновляем только значение конфигурации
"config_name = ? AND config_owner = ? AND config_cat = ? AND config_subcat = ?", // Условие поиска
array($key, $owner, $n, $editconfig) // Параметры для поиска
);
}
}
}
$dir = $owner == 'module' ? Cot::$cfg['modules_dir'] : Cot::$cfg['plugins_dir']; // Определяем директорию для модуля или плагина
// Если существует файл конфигурации, запускаем его
if (file_exists($dir . "/" .$n . "/setup/" .$n. ".configure.php")) { // Если файл конфигурации существует
include $dir . "/" .$n . "/setup/" . $n . ".configure.php"; // Подключаем его
}
}
}
$rstructurecode = cot_import('rstructurecode', 'P', 'ARR'); // Импортируем параметр 'rstructurecode' как массив из POST-запроса
$rstructurepath = cot_import('rstructurepath', 'P', 'ARR'); // Импортируем параметр 'rstructurepath' как массив из POST-запроса
$rstructuretitle = cot_import('rstructuretitle', 'P', 'ARR'); // Импортируем параметр 'rstructuretitle' как массив из POST-запроса
$rstructuredesc = cot_import('rstructuredesc', 'P', 'ARR'); // Импортируем параметр 'rstructuredesc' как массив из POST-запроса
$rstructureicon = cot_import('rstructureicon', 'P', 'ARR'); // Импортируем параметр 'rstructureicon' как массив из POST-запроса
$rstructurelocked = cot_import('rstructurelocked', 'P', 'ARR'); // Импортируем параметр 'rstructurelocked' как массив из POST-запроса
// Если импортированные данные не пустые, оставляем их, иначе устанавливаем пустой массив
$rstructurecode = !empty($rstructurecode) ? $rstructurecode : []; // Если 'rstructurecode' не пустой, используем его, иначе устанавливаем пустой массив
$rstructurepath = !empty($rstructurepath) ? $rstructurepath : []; // Если 'rstructurepath' не пустой, используем его, иначе устанавливаем пустой массив
$rstructuretitle = !empty($rstructuretitle) ? $rstructuretitle : []; // Если 'rstructuretitle' не пустой, используем его, иначе устанавливаем пустой массив
$rstructuredesc = !empty($rstructuredesc) ? $rstructuredesc : []; // Если 'rstructuredesc' не пустой, используем его, иначе устанавливаем пустой массив
$rstructureicon = !empty($rstructureicon) ? $rstructureicon : []; // Если 'rstructureicon' не пустой, используем его, иначе устанавливаем пустой массив
$rstructurelocked = !empty($rstructurelocked) ? $rstructurelocked : []; // Если 'rstructurelocked' не пустой, используем его, иначе устанавливаем пустой массив
$rtplmodearr = cot_import('rstructuretplmode', 'P', 'ARR'); // Импортируем параметр 'rstructuretplmode' как массив из POST-запроса
$rtplforcedarr = cot_import('rstructuretplforced', 'P', 'ARR'); // Импортируем параметр 'rstructuretplforced' как массив из POST-запроса
$rtplcodearr = cot_import('rstructuretplcode', 'P', 'ARR'); // Импортируем параметр 'rstructuretplcode' как массив из POST-запроса
// Если импортированные данные не пустые, оставляем их, иначе устанавливаем пустой массив
$rtplmodearr = !empty($rtplmodearr) ? $rtplmodearr : []; // Если 'rstructuretplmode' не пустой, используем его, иначе устанавливаем пустой массив
$rtplforcedarr = !empty($rtplforcedarr) ? $rtplforcedarr : []; // Если 'rstructuretplforced' не пустой, используем его, иначе устанавливаем пустой массив
$rtplcodearr = !empty($rtplcodearr) ? $rtplcodearr : []; // Если 'rstructuretplcode' не пустой, используем его, иначе устанавливаем пустой массив
/* === Hook === */
foreach (cot_getextplugins('admin.structure.update.first') as $pl) { // Выполняем хуки перед обновлением структуры, чтобы подключить дополнительные расширения
include $pl; // Включаем расширение, если оно подключено
}
/* ===== */
foreach ($rstructurecode as $i => $k) { // Проходим по всем элементам массива $rstructurecode
$oldrow = Cot::$db->query('SELECT * FROM ' . Cot::$db->structure . // Выполняем запрос к базе данных, чтобы получить старые данные структуры по её ID
" WHERE structure_id=" . (int) $i)->fetch(); // Извлекаем строку данных структуры, идентифицированную через $i (ID)
if (isset($rstructurecode[$i])) { // Проверяем, существует ли код структуры для данного элемента
$rstructure['structure_code'] = preg_replace( // Очищаем значение кода структуры от нежелательных символов
'#[^\w\p{L}\-]#u', // Регулярное выражение для удаления символов, кроме букв, цифр и дефиса
'', // Заменяем все неподобающие символы на пустую строку
cot_import($rstructurecode[$i], 'D', 'TXT') // Импортируем и обрабатываем код структуры из массива $rstructurecode
);
}
if (isset($rstructurepath[$i])) { // Проверяем, существует ли путь структуры для текущего элемента
$rstructure['structure_path'] = cot_import($rstructurepath[$i], 'D', 'TXT'); // Импортируем путь структуры и присваиваем его переменной
}
if (isset($rstructuretitle[$i])) { // Проверяем, существует ли заголовок структуры для текущего элемента
$rstructure['structure_title'] = cot_import($rstructuretitle[$i], 'D', 'TXT'); // Импортируем заголовок структуры и присваиваем его переменной
}
if (isset($rstructuredesc[$i])) { // Проверяем, существует ли описание структуры для текущего элемента
$rstructure['structure_desc'] = cot_import($rstructuredesc[$i], 'D', 'TXT'); // Импортируем описание структуры и присваиваем его переменной
}
if (isset($rstructureicon[$i])) { // Проверяем, существует ли иконка структуры для текущего элемента
$rstructure['structure_icon'] = cot_import($rstructureicon[$i], 'D', 'TXT'); // Импортируем иконку структуры и присваиваем её переменной
}
if (isset($rstructurelocked[$i]) && cot_import($rstructurelocked[$i], 'D', 'BOL') !== null) { // Проверяем, существует ли параметр блокировки структуры и его значение
$rstructure['structure_locked'] = (cot_import($rstructurelocked[$i], 'D', 'BOL')) ? 1 : 0; // Импортируем и присваиваем значение блокировки структуры (1 - заблокировано, 0 - не заблокировано)
}
if (!empty(Cot::$extrafields[Cot::$db->structure])) { // Проверяем, есть ли дополнительные поля для структуры
foreach (Cot::$extrafields[Cot::$db->structure] as $exfld) { // Перебираем все дополнительные поля для структуры
$inputName = 'rstructure' . $exfld['field_name'] . '_' . $i; // Формируем имя поля ввода для текущего дополнительного поля
// TODO Мы должны проверить, имеет ли дополнительное поле значение по умолчанию или оно обязательно для заполнения
if (isset($_POST[$inputName])) { // Проверяем, передано ли значение для дополнительного поля
$rstructure['structure_' . $exfld['field_name']] = cot_import_extrafields( // Импортируем значение дополнительного поля
$inputName, // Имя поля ввода
$exfld, // Сами данные поля
'P', // Источник данных (POST)
$oldrow['structure_' . $exfld['field_name']], // Старое значение поля из базы
'structure_' // Префикс для имени поля в базе
);
}
}
}
($rstructure['structure_code'] != 'all') || cot_error('adm_structure_code_reserved', 'rstructurecode'); // Проверяем, не является ли код структуры 'all', если да, то выводим ошибку "adm_structure_code_reserved"
$rstructure['structure_code'] || cot_error('adm_structure_code_required', 'rstructurecode'); // Если код структуры не пуст, иначе выводим ошибку "adm_structure_code_required"
$rstructure['structure_path'] || cot_error('adm_structure_path_required', 'rstructurepath'); // Если путь структуры не пуст, иначе выводим ошибку "adm_structure_path_required"
$rstructure['structure_title'] || cot_error('adm_structure_title_required', 'rstructuretitle'); // Если название структуры не пусто, иначе выводим ошибку "adm_structure_title_required"
$rtplmode = isset($rtplmodearr[$i]) ? cot_import($rtplmodearr[$i], 'D', 'INT') : 0; // Если для текущего элемента существует tplmode, то импортируем его как целое число, иначе устанавливаем значение 0
$rtplcode = isset($rtplcodearr[$i]) ? cot_import($rtplcodearr[$i], 'D', 'TXT') : ''; // Если для текущего элемента существует tplcode, то импортируем его как строку, иначе оставляем пустым
$rstructure['structure_tpl'] = ''; // Инициализируем переменную 'structure_tpl' как пустую строку
if (!empty($rtplcode) && (empty($rtplmode) || $rtplmode == 4)) { // Если tplcode не пуст и tplmode пуст или равен 4
$rstructure['structure_tpl'] = $rtplcode; // Присваиваем tplcode значению 'structure_tpl'
} elseif ($rtplmode == 3 && !empty($rtplforcedarr[$i])) { // Если tplmode равен 3 и tplforced для текущего элемента не пуст
$rstructure['structure_tpl'] = cot_import($rtplforcedarr[$i], 'D', 'TXT'); // Присваиваем значение из forcedarr
} elseif ($rtplmode == 2) { // Если tplmode равен 2
$rstructure['structure_tpl'] = 'same_as_parent'; // Присваиваем 'same_as_parent' как значение 'structure_tpl'
} elseif ($rtplmode == 1) { // Если tplmode равен 1
$rstructure['structure_tpl'] = ''; // Оставляем 'structure_tpl' пустым
}
if (!cot_error_found()) { // Проверяем, не были ли найдены ошибки
$res = cot_structure_update($n, $i, $oldrow, $rstructure, $is_module); // Обновляем структуру с помощью функции cot_structure_update
if (is_array($res)) { // Если результат обновления является массивом (с ошибками)
cot_error($res[0], $res[1]); // Выводим ошибку
}
}
} // закрываем foreach ($rstructurecode as $i => $k)
cot_extrafield_movefiles(); // Перемещаем файлы, связанные с дополнительными полями
cot_auth_clear('all'); // Очищаем кэш прав доступа для всех пользователей
if ($cache) { // Если объект кэша существует
$cache->clear(); // Очищаем кэш
}
/* === Hook === */
foreach (cot_getextplugins('admin.structure.update.done') as $pl) { // Загружаем плагины для завершения обновления структуры
include $pl; // Включаем каждый плагин
}
/* ===== */
if (!cot_error_found()) { // Если нет ошибок после обновления структуры
cot_message('Updated'); // Выводим сообщение об успешном обновлении
} else {
cot_error('adm_structure_somenotupdated'); // Если есть ошибки, выводим сообщение о том, что не все обновления прошли успешно
}
cot_redirect(cot_url('admin', 'm=structure&n='.$n.'&mode='.$mode.'&d='.$durl, '', true)); // Перенаправляем на страницу с результатами обновления
} // Закрываем if ($a == 'update' && !empty($_POST))
elseif ($a == 'add' && !empty($_POST)) { // Если запрос добавления и данные отправлены через POST
$rstructure['structure_code'] = preg_replace('#[^\w\p{L}\-]#u', '', cot_import('rstructurecode', 'P', 'TXT')); // Убираем запрещенные символы из кода структуры
$rstructure['structure_path'] = cot_import('rstructurepath', 'P', 'TXT'); // Получаем путь структуры из POST
$rstructure['structure_title'] = cot_import('rstructuretitle', 'P', 'TXT'); // Получаем заголовок структуры из POST
$rstructure['structure_desc'] = cot_import('rstructuredesc', 'P', 'TXT'); // Получаем описание структуры из POST
$rstructure['structure_icon'] = cot_import('rstructureicon', 'P', 'TXT'); // Получаем иконку структуры из POST
$rstructure['structure_locked'] = (cot_import('rstructurelocked', 'P', 'BOL')) ? 1 : 0; // Определяем, заблокирована ли структура, и присваиваем значение
$rstructure['structure_area'] = $n; // Устанавливаем область структуры равной текущему расширению
$rtplmode = cot_import('rtplmode', 'P', 'INT'); // Получаем режим шаблона из POST
$rtplcode = cot_import('rtplcode', 'P', 'TXT'); // Получаем код шаблона из POST
if (!empty(Cot::$extrafields[Cot::$db->structure])) { // Проверяем, есть ли дополнительные поля для структуры
foreach (Cot::$extrafields[Cot::$db->structure] as $exfld) { // Проходим по всем дополнительным полям
$inputName = 'rstructure' . $exfld['field_name']; // Формируем имя поля из префикса и имени дополнительного поля
// TODO Добавить новую запись. Нужно проверить, имеет ли дополнительное поле значение по умолчанию или оно обязательно
if (isset($_POST[$inputName])) { // Если поле передано в POST
$rstructure['structure_' . $exfld['field_name']] = cot_import_extrafields($inputName, // Импортируем значение дополнительного поля
$exfld, 'P', '', 'structure_'); // Сохранение в массив структуры с префиксом "structure_"
}
}
}
($rstructure['structure_code'] != 'all') || cot_error('adm_structure_code_reserved', 'rstructurecode'); // Проверка, что код структуры не равен 'all', иначе ошибка
$rstructure['structure_code'] || cot_error('adm_structure_code_required', 'rstructurecode'); // Проверка, что код структуры не пустой, иначе ошибка
$rstructure['structure_path'] || cot_error('adm_structure_path_required', 'rstructurepath'); // Проверка, что путь структуры не пустой, иначе ошибка
$rstructure['structure_title'] || cot_error('adm_structure_title_required', 'rstructuretitle'); // Проверка, что название структуры не пустое, иначе ошибка
if (!empty($rtplcode)) { // Если код шаблона задан
$rstructure['structure_tpl'] = $rtplcode; // Присваиваем код шаблона
} elseif ($rtplmode == 3) { // Если режим шаблона 3
$rstructure['structure_tpl'] = cot_import('rtplforced', 'P', 'TXT'); // Присваиваем принудительно заданный шаблон
} elseif ($rtplmode == 2) { // Если режим шаблона 2
$rstructure['structure_tpl'] = 'same_as_parent'; // Присваиваем шаблон, одинаковый с родительским
} else { // Если ни одно из условий не выполнено
$rstructure['structure_tpl'] = ''; // Присваиваем пустое значение для шаблона
}
/* === Hook === */
foreach (cot_getextplugins('admin.structure.add.first') as $pl) { // Выполняем подключение плагинов на первом этапе добавления структуры
include $pl; // Подключаем плагин
}
/* ===== */
if (!cot_error_found()) { // Если не найдены ошибки
$res = cot_structure_add($n, $rstructure, $is_module); // Добавляем структуру, передавая параметры
if ($res === true) { // Если результат добавления структуры успешен
cot_extrafield_movefiles(); // Перемещаем файлы дополнительных полей
/* === Hook === */
foreach (cot_getextplugins('admin.structure.add.done') as $pl) { // Выполняем подключение плагинов на этапе завершения добавления структуры
include $pl; // Подключаем плагин
}
/* ===== */
cot_message('Added'); // Выводим сообщение об успешном добавлении
} elseif (is_array($res)) { // Если результат добавления структуры - это массив с ошибкой
cot_error($res[0], $res[1]); // Выводим ошибку
} else { // В случае других ошибок
cot_error('Error'); // Выводим общую ошибку
}
}
cot_redirect(cot_url('admin', 'm=structure&n='.$n.'&mode='.$mode.'&d='.$durl, '', true)); // Перенаправляем пользователя на страницу структуры с соответствующими параметрами
} elseif ($a == 'delete') { // Если действие равно "удалить"
cot_check_xg(); // Проверка на XSRF (Cross-Site Request Forgery)
$data = Cot::$db->query( // Запрос к базе данных, чтобы получить данные о категории структуры
'SELECT structure_code, structure_count FROM ' . Cot::$db->structure .
' WHERE structure_area = :area AND structure_code = :code',
['area' => $n, 'code' => $c] // Параметры для запроса
)->fetch(); // Извлекаем данные
if (empty($data)) { // Если данные не найдены (категория не существует)
cot_error($c . ': ' . Cot::$L['adm_structure_category_not_exists']); // Выводим ошибку
} elseif( // Если категория не пуста или имеет подкатегории
$data['structure_count'] > 0 ||
!empty(cot_structure_children($n, $c, true, false, false))
) {
cot_error($c . ': ' . Cot::$L['adm_structure_category_not_empty']); // Выводим ошибку
}
if (!cot_error_found()) { // Если нет ошибок
if (cot_structure_delete($n, $c, $is_module)) { // Удаляем структуру
/* === Hook === */
foreach (cot_getextplugins('admin.structure.delete.done') as $pl) { // Выполняем подключение плагинов на этапе удаления
include $pl; // Подключаем плагин
}
/* ===== */
cot_message('Deleted'); // Выводим сообщение об успешном удалении
}
}
cot_redirect(cot_url('admin', 'm=structure&n='.$n.'&mode='.$mode.'&d='.$durl, '', true)); // Перенаправляем пользователя на страницу структуры с соответствующими параметрами
}
} elseif ($a == 'resyncall') { // Если действие равно "пересинхронизировать все"
cot_check_xg(); // Проверка на XSRF (Cross-Site Request Forgery)
$res = false; // Инициализация переменной результата
$area_sync = 'cot_'.$n.'_sync'; // Формируем название функции для синхронизации
if (function_exists($area_sync)) { // Если функция синхронизации существует
$res = true; // Устанавливаем результат в true
$sql = Cot::$db->query( // Запрос к базе данных для получения кодов категорий структуры
'SELECT structure_code FROM ' . Cot::$db->structure . ' WHERE structure_area=?',
$n // Параметры для запроса
);
foreach ($sql->fetchAll() as $row) { // Для каждой категории структуры
$cat = $row['structure_code']; // Получаем код категории
$items = $area_sync($cat); // Вызываем функцию синхронизации для категории
Cot::$db->update( // Обновляем количество элементов в структуре
Cot::$db->structure,
['structure_count' => (int) $items],
'structure_code=? AND structure_area=?',
[$cat, $n] // Параметры для обновления
);
}
$sql->closeCursor(); // Закрываем курсор запроса
}
/* === Hook === */
foreach (cot_getextplugins('admin.structure.resync.done') as $pl) { // Выполняем подключение плагинов на этапе пересинхронизации
include $pl; // Подключаем плагин
}
/* ===== */
// Если синхронизация успешна, выводим сообщение об успехе, иначе сообщение об ошибке
$res ? cot_message('Resynced') : cot_message("Error: function $area_sync doesn't exist."); // TODO i18n
// Если включен кэш, очищаем его
if (Cot::$cache && !empty(Cot::$cfg['cache_' . $n])) {
Cot::$cache->static->clearByUri(cot_url($n)); // Очищаем кэш для конкретного URI
}
// Перенаправляем пользователя на страницу структуры
cot_redirect(
cot_url('admin', ['m' => 'structure', 'n' => $n, 'mode' => $mode, 'd' => $durl], '', true)
);
}
$ext_info = cot_get_extensionparams($n, true); // Получаем информацию о расширении
$adminPath[] = array(cot_url('admin', 'm=extensions'), Cot::$L['Extensions']); // Добавляем ссылку на раздел расширений в навигацию
$urlParams = array('m' => 'extensions', 'a' => 'details'); // Устанавливаем параметры URL для страницы подробностей
if ($is_module) {
$urlParams['mod'] = $n; // Если это модуль, добавляем параметр 'mod'
} else {
$urlParams['pl'] = $n; // Если это плагин, добавляем параметр 'pl'
}
$adminPath[] = [cot_url('admin', $urlParams), $ext_info['name']]; // Добавляем ссылку на страницу расширения
$adminPath[] = [cot_url('admin', 'm=structure&n='.$n), Cot::$L['Structure']]; // Добавляем ссылку на структуру в навигацию
// Проверка на наличие ID или алиаса для структуры
if ($id > 0 || !empty($al)) {
$where = $id > 0 ? 'structure_id='.(int)$id : "structure_code='".$db->prep($al)."'"; // Устанавливаем условие для поиска структуры
$sql = Cot::$db->query("SELECT * FROM " . Cot::$db->structure . " WHERE $where LIMIT 1"); // Запрашиваем структуру
cot_die($sql->rowCount() == 0); // Если не найдено, завершаем выполнение с ошибкой
// Если задан режим 'all' или структура существует для текущего режима
} elseif ($mode && ($mode == 'all' || $structure[$n][$mode])) {
$sqlmask = ($mode == 'all') ? "structure_path NOT LIKE '%.%'" : "structure_path LIKE '".$db->prep($structure[$n][$mode]['rpath']).".%' AND structure_path NOT LIKE '".$db->prep($structure[$n][$mode]['rpath']).".%.%'"; // Создаем маску для фильтрации
// Запрашиваем структуры с учетом маски
$sql = $db->query("SELECT * FROM $db_structure WHERE structure_area='".$db->prep($n)."' AND $sqlmask ORDER BY structure_path ASC, structure_code ASC LIMIT $d, ".$maxrowsperpage);
// Получаем общее количество элементов для пагинации
$totalitems = $db->query("SELECT COUNT(*) FROM $db_structure WHERE structure_area='".$db->prep($n)."' AND $sqlmask")->fetchColumn();
// Генерируем пагинацию
$pagenav = cot_pagenav('admin', 'm=structure&n='.$n.'&mode='.$mode, $d, $totalitems, $maxrowsperpage, 'd', '', $cfg['jquery'] && $cfg['turnajax']);
} else { // В случае если не задан ни ID, ни алиас, и нет особого режима
// Запрашиваем все структуры для данного раздела
$sql = $db->query("SELECT * FROM $db_structure WHERE structure_area='".$db->prep($n)."' ORDER BY structure_path ASC, structure_code ASC LIMIT $d, ".$maxrowsperpage);
// Получаем общее количество элементов для пагинации
$totalitems = $db->query("SELECT COUNT(*) FROM $db_structure WHERE structure_area='".$db->prep($n)."'")->fetchColumn();
// Генерируем пагинацию
$pagenav = cot_pagenav('admin', 'm=structure&n='.$n, $d, $totalitems, $maxrowsperpage, 'd', '', $cfg['jquery'] && $cfg['turnajax']);
}
$t->assign(array(
'ADMIN_STRUCTURE_UPDATE_FORM_URL' => cot_url('admin', 'm=structure&n='.$n.'&mode='.$mode.'&a=update&d='.$durl), // Ссылка на форму обновления структуры
'ADMIN_PAGE_STRUCTURE_RESYNCALL' => cot_url('admin', 'm=structure&n='.$n.'&mode='.$mode.'&a=resyncall&'.cot_xg().'&d='.$durl), // Ссылка для синхронизации всех структур
'ADMIN_STRUCTURE_URL_EXTRAFIELDS' => cot_url('admin', 'm=extrafields&n='.$db_structure) // Ссылка на дополнительные поля структуры
));
$categoryList = []; // Массив для списка категорий
$ii = 0; // Индекс для подсчета элементов
/* === Hook - Part1 : Set === */
$extp = cot_getextplugins('admin.structure.loop'); // Получаем расширения для цикла
/* ===== */
// Проходим по всем строкам результата запроса
foreach ($sql->fetchAll() as $row) {
$ii++; // Увеличиваем индекс для каждой строки
// Дальше идет обработка каждой строки в цикле
$structureId = $row['structure_id']; // Идентификатор структуры
$structureCode = $row['structure_code']; // Код структуры
$pathfielddep = explode(".", $row['structure_path']); // Разделяем путь структуры на части
$pathfielddep = !empty($pathfielddep) ? count($pathfielddep) : 0; // Получаем количество частей пути
$structureLevel = ($pathfielddep > 0) ? $pathfielddep : 0; // Уровень структуры в иерархии
$pathspaceimg = ''; // Инициализируем переменную для визуальных отступов
for ($pathfielddepi = 1; $pathfielddepi < $pathfielddep; $pathfielddepi++) {
$pathspaceimg .= '.' . Cot::$R['admin_icon_blank']; // Добавляем иконку для каждого уровня иерархии
}
// @todo Не используйте код категории, используйте ID вместо
foreach ($structure[$n] as $catCode => $x) {
if ($catCode != 'all') { // Исключаем категорию "all"
$categoryList[$catCode] = $x['tpath']; // Добавляем в список категорий путь для каждой категории
}
}
if (empty($row['structure_tpl'])) {
$tplMode = '1'; // Если шаблон не указан, используем режим 1
} elseif ($row['structure_tpl'] == 'same_as_parent') {
$tplMode = '2'; // Если шаблон одинаков с родительским, используем режим 2
} else {
$tplMode = '3'; // Если шаблон указан, используем режим 3
if (!in_array($row['structure_tpl'], array_keys($categoryList))) {
$tplMode = '4'; // Если шаблон не найден в списке категорий, используем режим 4
}
}
$categoryTplCodeSelect = cot_selectbox(
$row['structure_tpl'], // Значение по умолчанию (код текущего шаблона)
'rstructuretplforced[' . $row['structure_id'] . ']', // Имя поля для выбора шаблона
array_keys($categoryList), // Список значений (категории)
array_values($categoryList), // Список отображаемых значений (пути категорий)
false // Не требуется указание пустого значения
);
$categoryTplCode = cot_inputbox(
'text', // Тип поля ввода
'rstructuretplcode[' . $row['structure_id'] . ']', // Имя поля ввода шаблона
$row['structure_tpl'], // Значение по умолчанию (текущий шаблон)
'maxlength="255"' // Ограничение на длину ввода
);
$categoryTpl = cot_radiobox(
$tplMode, // Значение, соответствующее выбранному режиму
'rstructuretplmode[' . $row['structure_id'] . ']', // Имя поля для выбора режима шаблона
['1', '2', '3', '4'], // Возможные значения режима
[
Cot::$L['adm_tpl_empty'], // Режим 1: Пустой шаблон
Cot::$L['adm_tpl_parent'], // Режим 2: Шаблон родителя
Cot::$L['adm_tpl_forced'] . ' ' . $categoryTplCodeSelect, // Режим 3: Принудительный шаблон с выбором
Cot::$L['adm_tpl_code'] . ' ' . $categoryTplCode, // Режим 4: Шаблон по коду с возможностью ввода
],
'', // Не указываем дополнительный класс или атрибут
'<br />', // Разделитель между радиокнопками
'', // Не указываем id
true // Ожидаем, что один из вариантов будет выбран по умолчанию
);
$children = cot_structure_children(
$row['structure_area'], // Область структуры (например, модуль или плагин)
$row['structure_code'], // Код текущей категории
true, // Включить дочерние элементы
false, // Исключить текущую категорию из результатов
false // Не использовать кэширование
);
$deleteUrl = cot_url(
'admin', // Раздел панели администрирования
[
'm' => 'structure', // Модуль управления структурами
'n' => $n, // Имя области (например, модуля или плагина)
'mode' => $mode, // Режим отображения
'a' => 'delete', // Действие (удаление категории)
'id' => $row['structure_id'], // ID структуры для удаления
'c' => $row['structure_code'], // Код категории
'd' => $durl, // Параметр постраничной навигации
'x' => Cot::$sys['xk'] // CSRF-токен для безопасности
]
);
$deleteConfirmUrl = cot_confirm_url($deleteUrl, 'admin'); // URL с подтверждением удаления
$t->assign([
// ID структуры
'ADMIN_STRUCTURE_ID' => $row['structure_id'],
// Поле ввода для кода структуры
'ADMIN_STRUCTURE_CODE' => cot_inputbox(
'text',
'rstructurecode[' . $row['structure_id'] . ']',
$row['structure_code'],
'maxlength="255"' // Ограничение длины
),
// Пробелы для иерархии
'ADMIN_STRUCTURE_SPACEIMG' => $pathspaceimg,
// Уровень вложенности структуры
'ADMIN_STRUCTURE_LEVEL' => $structureLevel,
// Иконка пути (в зависимости от позиции)
'ADMIN_STRUCTURE_PATHFIELDIMG' => (mb_strpos($row['structure_path'], '.') == 0) ?
Cot::$R['admin_icon_join1'] : Cot::$R['admin_icon_join2'],
// Поле ввода пути структуры
'ADMIN_STRUCTURE_PATH' => cot_inputbox(
'text',
'rstructurepath[' . $row['structure_id'] . ']',
$row['structure_path'],
'maxlength="255"' // Ограничение длины
),
// Выбор шаблона категории
'ADMIN_STRUCTURE_TPL' => $categoryTpl,
// Выпадающий список для выбора шаблона категории
'ADMIN_STRUCTURE_TPL_CODE_SELECT' => $categoryTplCodeSelect,
// Поле ввода пользовательского шаблона
'ADMIN_STRUCTURE_TPL_CODE' => $categoryTplCode,
// Поле ввода названия структуры
'ADMIN_STRUCTURE_TITLE' => cot_inputbox(
'text',
'rstructuretitle[' . $row['structure_id'] . ']',
$row['structure_title'],
'maxlength="255"' // Ограничение длины
),
// Поле ввода описания структуры
'ADMIN_STRUCTURE_DESC' => cot_inputbox(
'text',
'rstructuredesc[' . $row['structure_id'] . ']',
$row['structure_desc'],
'maxlength="255"' // Ограничение длины
),
// Поле ввода иконки структуры
'ADMIN_STRUCTURE_ICON' => cot_inputbox(
'text',
'rstructureicon[' . $row['structure_id'] . ']',
$row['structure_icon'],
'maxlength="128"' // Ограничение длины
),
// Чекбокс для блокировки категории
'ADMIN_STRUCTURE_LOCKED' => cot_checkbox(
$row['structure_locked'],
'rstructurelocked[' . $row['structure_id'] . ']' // Имя чекбокса
),
// Количество элементов в структуре
'ADMIN_STRUCTURE_COUNT' => $row['structure_count'],
// Возможность удаления структуры (если пустая и нет детей)
'ADMIN_STRUCTURE_CAN_DELETE' => $row['structure_count'] < 1 && empty($children),
// URL для перехода к категории на сайте
'ADMIN_STRUCTURE_JUMPTO_URL' => cot_url($n, 'c=' . $row['structure_code']),
// URL для управления правами доступа
'ADMIN_STRUCTURE_RIGHTS_URL' => $is_module
? cot_url('admin', 'm=rightsbyitem&ic=' . $n . '&io=' . $row['structure_code'])
: '',
// URL для редактирования структуры
'ADMIN_STRUCTURE_OPTIONS_URL' => cot_url(
'admin',
'm=structure&n=' . $n . '&d=' . $durl . '&id=' . $row['structure_id'] . '&' . cot_xg()
),
// URL для удаления структуры
'ADMIN_STRUCTURE_DELETE_URL' => $deleteUrl,
// Подтверждение удаления структуры
'ADMIN_STRUCTURE_DELETE_CONFIRM_URL' => $deleteConfirmUrl,
// Чередование классов (например, для зебры в таблице)
'ADMIN_STRUCTURE_ODDEVEN' => cot_build_oddeven($ii),
]);
if (isset(Cot::$cfg['legacyMode']) && Cot::$cfg['legacyMode']) { // Проверка режима совместимости
$t->assign([
'ADMIN_STRUCTURE_TPLMODE' => $categoryTpl, // @deprecated. Выбор (настройка) кода шаблона
'ADMIN_STRUCTURE_UPDATE_DEL_URL' => $deleteConfirmUrl, // @deprecated. Используйте ADMIN_STRUCTURE_DELETE_CONFIRM_URL
]);
}
if (!empty(Cot::$extrafields[Cot::$db->structure])) { // Проверка на наличие дополнительных полей
foreach (Cot::$extrafields[Cot::$db->structure] as $exfld) { // Обработка каждого дополнительного поля
$exfld_val = cot_build_extrafields('rstructure' . $exfld['field_name'] . '_' . $row['structure_id'], $exfld, $row['structure_' . $exfld['field_name']]); // Построение значения поля
$exfld_title = cot_extrafield_title($exfld, 'structure_'); // Получение заголовка поля
$t->assign(array(
'ADMIN_STRUCTURE_' . strtoupper($exfld['field_name']) => $exfld_val, // Значение дополнительного поля
'ADMIN_STRUCTURE_' . strtoupper($exfld['field_name']) . '_TITLE' => $exfld_title, // Заголовок дополнительного поля
'ADMIN_STRUCTURE_EXTRAFLD' => $exfld_val, // Значение дополнительного поля для шаблона
'ADMIN_STRUCTURE_EXTRAFLD_TITLE' => $exfld_title // Заголовок дополнительного поля для шаблона
));
$t->parse(($id || !empty($al)) ? 'MAIN.OPTIONS.EXTRAFLD' : 'MAIN.DEFAULT.ROW.EXTRAFLD'); // Парсинг шаблона
}
}
/* === Hook - Part2 : Include === */
foreach ($extp as $pl) { // Включение хуков
include $pl;
}
/* ===== */
if ($id || !empty($al)) { // Проверка, редактируется ли структура или выбран алиас
require_once cot_incfile('configuration'); // Подключение файла конфигурации
$adminTitle .= ': ' . htmlspecialchars($row['structure_title']); // Добавление заголовка
$adminPath[] = [ // Добавление пути в админской панели
cot_url('admin', ['m' => 'structure', 'n' => $n, 'id' => $id]),
$row['structure_title'],
];
$optionslist = cot_config_list($is_module ? 'module' : 'plug', $n, $row['structure_code']); // Получение списка конфигураций
/* === Hook - Part1 : Set === */
$extp = cot_getextplugins('admin.config.edit.loop'); // Хуки для цикла конфигурации
/* ===== */
foreach ($optionslist as $configRow) { // Обработка каждой строки конфигурации
list($title, $hint) = cot_config_titles($configRow['config_name'], $configRow['config_text']); // Заголовок и подсказка конфигурации
if ($configRow['config_type'] == COT_CONFIG_TYPE_SEPARATOR) { // Если это разделитель
$t->assign('ADMIN_CONFIG_FIELDSET_TITLE', $title); // Название разделителя
$t->parse('MAIN.OPTIONS.CONFIG.ADMIN_CONFIG_ROW.ADMIN_CONFIG_FIELDSET_BEGIN'); // Парсинг начала раздела
} else { // Если это обычная настройка
$t->assign([
'ADMIN_CONFIG_ROW_CONFIG' => cot_config_input($configRow), // Ввод конфигурации
'ADMIN_CONFIG_ROW_CONFIG_TITLE' => $title, // Заголовок конфигурации
'ADMIN_CONFIG_ROW_CONFIG_MORE_URL' => cot_url( // Ссылка для сброса конфигурации
'admin',
[
'm' => 'structure',
'n' => $n,
'd' => $durl,
'id' => $row['structure_id'],
'al' => $row['structure_code'],
'a' => 'reset',
'v' => $configRow['config_name'],
'x' => Cot::$sys['xk'],
]
),
'ADMIN_CONFIG_ROW_CONFIG_MORE' => $hint // Подсказка для конфигурации
]);
/* === Hook - Part2 : Include === */
foreach ($extp as $pl) { // Хуки для настроек
include $pl;
}
/* ===== */
$t->parse('MAIN.OPTIONS.CONFIG.ADMIN_CONFIG_ROW.ADMIN_CONFIG_ROW_OPTION'); // Парсинг строки опции
}
$t->parse('MAIN.OPTIONS.CONFIG.ADMIN_CONFIG_ROW'); // Парсинг строки конфигурации
}
/* === Hook === */
foreach (cot_getextplugins('admin.config.edit.tags') as $pl) { // Хуки для тегов конфигурации
include $pl;
}
/* ===== */
$t->assign('CONFIG_HIDDEN', cot_inputbox('hidden', 'editconfig', $row['structure_code'])); // Скрытое поле для отправки кода структуры
$t->parse('MAIN.OPTIONS.CONFIG'); // Парсинг конфигурации
}
$t->parse(($id || !empty($al)) ? 'MAIN.OPTIONS' : 'MAIN.DEFAULT.ROW'); // Парсинг шаблона в зависимости от режима
}
unset($row); // Очистка строки данных
if (!$id && empty($al)) { // Проверка на отсутствие ID и алиаса
$t->assign([
'ADMIN_STRUCTURE_PAGINATION_PREV' => $pagenav['prev'], // Предыдущая страница пагинации
'ADMIN_STRUCTURE_PAGNAV' => $pagenav['main'], // Навигация пагинации
'ADMIN_STRUCTURE_PAGINATION_NEXT' => $pagenav['next'], // Следующая страница пагинации
'ADMIN_STRUCTURE_TOTALITEMS' => $totalitems, // Общее количество элементов
'ADMIN_STRUCTURE_COUNTER_ROW' => $ii, // Счётчик строк
]);
$t->parse('MAIN.DEFAULT'); // Парсинг основного шаблона
// Очистка буфера, если он содержит данные таблицы обновлений
$uri = str_replace('&_ajax=1', '', $_SERVER['REQUEST_URI']); // Удаление AJAX-параметра из URI
$hash = md5($uri); // Генерация хэша URI
if (isset($_SESSION['cot_buffer']) && isset($_SESSION['cot_buffer'][$hash]) && is_array($_SESSION['cot_buffer'][$hash]['rstructurecode'])) {
unset($_SESSION['cot_buffer'][$hash]); // Удаление буфера
}
// Форма для добавления новой категории
$categoryTplCodeSelect = !empty($categoryList)
? cot_selectbox(
null,
'rtplforced',
array_keys($categoryList),
array_values($categoryList),
false
)
: ''; // Выпадающий список шаблонов категорий
$categoryTplCode = cot_inputbox('text', 'rtplcode', null, 'maxlength="255"'); // Поле для кода шаблона
$categoryTpl = !empty($categoryList)
? cot_radiobox(
null,
'rtplmode',
['1', '2', '3', '4'],
[
Cot::$L['adm_tpl_empty'], // Пустой шаблон
Cot::$L['adm_tpl_parent'], // Родительский шаблон
Cot::$L['adm_tpl_forced'] . ' ' . $categoryTplCodeSelect, // Принудительный шаблон
Cot::$L['adm_tpl_code'] . ' ' . $categoryTplCode, // Код шаблона
],
'',
'<br />',
'',
true
)
: ''; // Радиобокс выбора шаблона
$t->assign([
'ADMIN_STRUCTURE_URL_FORM_ADD' => cot_url( // URL для добавления категории
'admin',
['m' => 'structure', 'n' => $n, 'mode' => $mode, 'a' => 'add', 'd' => $durl]
),
'ADMIN_STRUCTURE_CODE' => cot_inputbox('text', 'rstructurecode', null), // Поле для кода структуры
'ADMIN_STRUCTURE_PATH' => cot_inputbox('text', 'rstructurepath', null, 'maxlength="16"'), // Поле для пути структуры
'ADMIN_STRUCTURE_TITLE' => cot_inputbox('text', 'rstructuretitle', null, 'maxlength="100"'), // Поле для названия структуры
'ADMIN_STRUCTURE_DESC' => cot_inputbox('text', 'rstructuredesc', null, 'maxlength="255"'), // Поле для описания
'ADMIN_STRUCTURE_ICON' => cot_inputbox('text', 'rstructureicon', null, 'maxlength="128"'), // Поле для иконки
'ADMIN_STRUCTURE_LOCKED' => cot_checkbox(null, 'rstructurelocked'), // Чекбокс блокировки
'ADMIN_STRUCTURE_TPL' => $categoryTpl, // Радиобокс шаблона
]);
if (isset(Cot::$cfg['legacyMode']) && Cot::$cfg['legacyMode']) { // Поддержка устаревшего режима
$t->assign([
'ADMIN_STRUCTURE_TPLMODE' => $categoryTpl, // Устаревший параметр шаблона
]);
}
// Добавление дополнительных полей
if (!empty(Cot::$extrafields[Cot::$db->structure])) {
foreach (Cot::$extrafields[Cot::$db->structure] as $exfld) { // Перебор дополнительных полей
$exfld_val = cot_build_extrafields('rstructure' . $exfld['field_name'], $exfld, null); // Построение поля
$exfld_title = cot_extrafield_title($exfld, 'structure_'); // Заголовок поля
$t->assign([
'ADMIN_STRUCTURE_' . strtoupper($exfld['field_name']) => $exfld_val, // Значение поля
'ADMIN_STRUCTURE_' . strtoupper($exfld['field_name']) . '_TITLE' => $exfld_title, // Заголовок поля
'ADMIN_STRUCTURE_EXTRAFLD' => $exfld_val, // Поле для вывода
'ADMIN_STRUCTURE_EXTRAFLD_TITLE' => $exfld_title, // Заголовок для вывода
]);
$t->parse('MAIN.NEWCAT.EXTRAFLD'); // Парсинг дополнительных полей
}
}
$t->parse('MAIN.NEWCAT'); // Парсинг блока для новой категории
}
cot_display_messages($t); // Отображение сообщений (уведомлений) в шаблоне
/* === Hook === */
foreach (cot_getextplugins('admin.structure.tags') as $pl) { // Подключение хуков для тега admin.structure.tags
include $pl; // Включение плагина
}
/* ===== */
$t->parse('MAIN'); // Парсинг основного блока шаблона
$adminMain = $t->text('MAIN'); // Вывод содержимого основного блока в переменную
}
Comments (0)
Content author
Offline
Administrator
Last logged: 2026-07-05 18:32
- Page published: 2025-01-28 19:25
- Last update: 2025-01-28 20:19