Описание файла page.main.php в контексте движка Cotonti CMF
1. Основное назначение и место в системе Cotonti
Файл page.main.php, расположенный в директории /modules/page/inc движка Cotonti CMF, является центральным элементом для обработки логики отображения страницы на сайте. Он отвечает за формирование и вывод данных, связанных с отдельной страницей контента в системе. Этот файл взаимодействует с другими модулями Cotonti, используя хранилище данных, переменные конфигурации и шаблоны для отображения информации на веб-странице.
Основная цель этого файла — обработка данных страницы, их подготовка для вывода в шаблон и взаимодействие с функциональностью системы, такой как кеширование, обработка файлов, отображение вкладок, мета-данных и др. Он управляет тем, как будет представлена конкретная страница (например, страница статьи, файла, или любой другой страницы в контексте сайта).
2. Взаимодействие с системой и другими частями сайта
Этот файл взаимодействует с несколькими компонентами системы:
- База данных: Извлекает данные страницы (например, заголовки, описание, мета-данные, содержимое) из базы данных.
- Шаблоны: Обрабатывает шаблон страницы, наполняет его данными и выводит результат с помощью объекта
XTemplate. - Кеширование: Используется для статического кэширования страницы с целью повышения производительности.
- Плагины: Файл взаимодействует с внешними плагинами, через хуки, для добавления дополнительной функциональности.
3. Переменные, хуки, методы, функции, классы
Переменные:
$pag: Массив данных, содержащий информацию о странице, такую как заголовок, описание, мета-данные и другие параметры.$cat: Массив, содержащий данные категории страницы.$t: ОбъектXTemplate, который используется для парсинга и вывода шаблона страницы.$pageStaticCacheEnabled: Переменная, определяющая, включено ли статическое кэширование.$id: Идентификатор страницы.$al: Прочие параметры для обработки URL (например, алиас страницы).$pg: Параметр для пагинации (страницы).
Хуки:
page.main: Хук для расширения функциональности страницы. Он позволяет подключать плагины, которые могут изменять вывод страницы или выполнять дополнительные действия.page.tags: Хук для подключения внешних плагинов, взаимодействующих с тегами страницы.
Методы и функции:
cot_tplfile(): Функция для получения пути к шаблону страницы.cot_url(): Функция для генерации URL для страницы, с возможностью добавления параметров.cot_title(): Формирует полный заголовок страницы.cot_generate_pagetags(): Генерирует теги для страницы, используя данные из массива$pagи других источников.cot_declension(): Функция для склонения слов, например, для отображения количества скачиваний.cot_pagenav(): Генерация навигации по страницам (например, для табов или пагинации).cot_display_messages(): Выводит сообщения об ошибках или уведомлениях.cot_rc(): Функция для работы с ресурсами (например, для вывода иконок).cot_build_filesize(): Функция для форматирования размера файла в человекочитаемый вид.
Классы:
XTemplate: Класс для работы с шаблонами. В данном файле он используется для парсинга и вывода данных в шаблон страницы.Cot::$out: Объект, который управляет выводом данных на страницу (например, мета-данные, заголовки и т. д.).
4. Суть содержания кода
Код этого файла выполняет несколько ключевых задач:
- Обработка мета-данных: В начале файла происходит установка мета-заголовков, описаний и ключевых слов для страницы, используя данные из массива
$pag. - Подготовка и вывод контента: Включает обработку различных вкладок на странице, подготовку URL и мета-информации, а также парсинг шаблонов с выводом соответствующего контента.
- Файлы и скачивания: Если страница содержит файл, проверяется доступность этого файла для скачивания, в зависимости от прав пользователя, и отображается информация о файле (например, размер, количество скачиваний).
- Обработка ошибок и сообщений: Все сообщения об ошибках или уведомления выводятся с помощью функции
cot_display_messages. - Пагинация: Если страница состоит из нескольких вкладок или страниц, реализуется навигация между ними, а также обработка динамической генерации ссылок для переходов.
5. Использование владельцем сайта
Владелец сайта может использовать этот файл для создания и настройки контента на страницах своего сайта. Например, он может:
- Разбивать контент на несколько вкладок с помощью маркера
[ newpage ]
- Настроить мета-данные страниц для SEO.
- Обрабатывать доступ к файлам для скачивания в зависимости от прав пользователя.
- Добавлять кастомные расширения через хуки и плагины.
- Настроить кэширование страниц для повышения производительности.
6. Стиль написания кода и совместимость с PHP
Стиль написания кода в данном файле можно охарактеризовать как:
- Чистый и понятный: Код разбит на логические блоки, каждый из которых отвечает за отдельную задачу.
- Согласованный: Использование стандартных функций Cotonti для работы с URL, мета-данными, и шаблонами.
Код совместим с версиями PHP 5.6 и выше, так как в нем не используются устаревшие функции или конструкции, характерные для более старых версий PHP. Для успешного выполнения необходима поддержка расширений PHP, таких как mbstring (для работы с многобайтовыми строками) и gettext (для работы с переводами).
Заключение
Файл page.main.php является важным компонентом для обработки и отображения контента страницы в Cotonti CMF. Он позволяет гибко управлять отображением страниц, использовать различные вкладки, обрабатывать мета-данные, управлять доступом к файлам и генерировать динамическую навигацию по страницам. Владелец сайта может использовать его для улучшения функциональности и производительности сайта, а также для создания кастомизированных решений через хуки и плагины
defined('COT_CODE') or die('Wrong URL'); // Проверка, что код был вызван через Cotonti CMF, если нет — завершение выполнения
list(Cot::$usr['auth_read'], Cot::$usr['auth_write'], Cot::$usr['isadmin']) = cot_auth('page', 'any'); // Получение прав доступа пользователя для работы с модулями страницы (чтение, запись, админские права)
cot_block(Cot::$usr['auth_read']); // Проверка прав на чтение, если их нет — остановка выполнения (пользователь не может просматривать страницу)
$id = cot_import('id', 'G', 'INT'); // Получение параметра 'id' из GET-запроса, приведение к целочисленному типу
$al = Cot::$db->prep(cot_import('al', 'G', 'TXT')); // Получение параметра 'al' из GET-запроса, обработка строки для предотвращения SQL-инъекций
$c = cot_import('c', 'G', 'TXT'); // Получение параметра 'c' из GET-запроса, обработка строки для безопасной вставки в запрос
$pg = cot_import('pg', 'G', 'INT'); // Получение параметра 'pg' из GET-запроса, приведение к целочисленному типу
$join_columns = isset($join_columns) ? $join_columns : ''; // Инициализация переменной $join_columns, если она не задана, она будет пустой
$join_condition = isset($join_condition) ? $join_condition : ''; // Инициализация переменной $join_condition, если она не задана, она будет пустой
/* === Hook === */
foreach (cot_getextplugins('page.first') as $pl) { // Прохождение по списку плагинов для хука 'page.first'
include $pl; // Подключение каждого плагина из списка
}
/* ===== */
if ($id > 0 || !empty($al)) { // Если id больше 0 или alias страницы не пустой
$where = (!empty($al)) ? "p.page_alias='".$al."'" : 'p.page_id='.$id; // Формирование условия для поиска: если alias существует, ищем по alias, иначе по id
if (!empty($c)) { // Если категория 'c' не пуста
$where .= " AND p.page_cat = " . Cot::$db->quote($c); // Добавление условия для фильтрации по категории
}
$sql_page = Cot::$db->query("SELECT p.*, u.* $join_columns
FROM $db_pages AS p $join_condition
LEFT JOIN $db_users AS u ON u.user_id=p.page_ownerid
WHERE $where LIMIT 1"); // Выполнение SQL-запроса для получения данных страницы и её владельца из таблиц базы данных
}
if (!$id && empty($al) || !$sql_page || $sql_page->rowCount() == 0) { // Если id пустое и alias тоже пустой или запрос не вернул результатов
cot_die_message(404); // Отображение ошибки 404 (страница не найдена)
}
$pag = $sql_page->fetch(); // Извлечение первой строки из результата запроса SQL для страницы
list(Cot::$usr['auth_read'], Cot::$usr['auth_write'], Cot::$usr['isadmin'], Cot::$usr['auth_download']) = cot_auth('page', $pag['page_cat'], 'RWA1'); // Получение прав доступа для пользователя для конкретной страницы и её категории (чтение, запись, админ, скачивание)
cot_block(Cot::$usr['auth_read']); // Проверка наличия прав на чтение, если их нет — остановка выполнения (пользователь не может просматривать страницу)
$al = empty($pag['page_alias']) ? '' : $pag['page_alias']; // Присваивание переменной $al значения alias страницы, если он пустой — присваиваем пустую строку
$id = (int) $pag['page_id']; // Приведение id страницы к целочисленному типу
$cat = Cot::$structure['page'][$pag['page_cat']]; // Получение информации о категории страницы из структуры сайта
$sys['sublocation'] = $pag['page_title']; // Установка подзаголовка для текущей страницы в системной переменной
$pag['page_begin_noformat'] = $pag['page_begin']; // Присваивание начального содержимого страницы в переменную без форматирования
$pag['page_tab'] = empty($pg) ? 0 : $pg; // Присваивание переменной $pag['page_tab'] значения параметра страницы (если пустой — 0)
$urlParams = ['c' => $pag['page_cat']]; // Инициализация массива параметров для URL с категорией страницы
if (!empty($al)) { // Если alias страницы не пустой
$urlParams['al'] = $al; // Добавляем параметр 'al' в массив URL
} else { // Если alias пустой
$urlParams['id'] = $id; // Добавляем параметр 'id' в массив URL
}
$pag['page_pageurl'] = cot_url('page', $urlParams, '', true); // Генерация полного URL для страницы с учётом параметров
if (
(
$pag['page_state'] == COT_PAGE_STATE_PENDING
|| $pag['page_state'] == COT_PAGE_STATE_DRAFT
|| $pag['page_begin'] > Cot::$sys['now']
|| ($pag['page_expire'] > 0 && Cot::$sys['now'] > $pag['page_expire'])
)
&& (!Cot::$usr['isadmin'] && Cot::$usr['id'] != $pag['page_ownerid'])
) { // Проверка состояния страницы, доступности и прав доступа: если страница в ожидании, черновик, не начала действовать или уже истекла
cot_log("Attempt to directly access an un-validated or future/expired page", 'sec', 'page', 'error'); // Логирование попытки доступа к невалидной или будущей/истекшей странице
cot_die_message(403, TRUE); // Отправка сообщения об ошибке с кодом 403 (Forbidden)
}
if (mb_substr($pag['page_text'], 0, 6) == 'redir:') { // Если текст страницы начинается с 'redir:', это значит, что нужно выполнить редирект
$env['status'] = '303 See Other'; // Установка HTTP статуса 303, который указывает на редирект
$redir = trim(str_replace('redir:', '', $pag['page_text'])); // Извлекаем URL для редиректа из текста страницы
$sql_page_update = Cot::$db->query("UPDATE $db_pages SET page_filecount=page_filecount+1 WHERE page_id=$id"); // Увеличиваем счётчик файлов для страницы
header('Location: ' . (preg_match('#^(http|ftp)s?://#', $redir) ? '' : COT_ABSOLUTE_URL) . $redir); // Выполняем редирект на указанный URL
exit; // Завершаем выполнение скрипта
} elseif (mb_substr($pag['page_text'], 0, 8) == 'include:') { // Если текст страницы начинается с 'include:', загружаем внешний файл
$pag['page_text'] = cot_readraw('datas/html/'.trim(mb_substr($pag['page_text'], 8, 255))); // Чтение содержимого файла и присваивание его тексту страницы
}
if ($pag['page_file'] && $a == 'dl' && (($pag['page_file'] == 2 && Cot::$usr['auth_download']) || $pag['page_file'] == 1)) { // Проверка наличия файла и разрешений на его скачивание
/* === Hook === */
foreach (cot_getextplugins('page.download.first') as $pl) { // Вызов хуков перед скачиванием
include $pl; // Включаем плагины
}
/* ===== */
// Hotlinking protection
if (
isset($_SESSION['dl'])
&& $_SESSION['dl'] != $id
&& isset($_SESSION['cat'])
&& $_SESSION['cat'] != $pag['page_cat']
) { // Защита от горячих ссылок: проверка, если пользователь пытается скачать файл с другого источника
cot_redirect($pag['page_pageurl']); // Перенаправление на URL страницы
}
unset($_SESSION['dl']); // Очистка сессии о скачивании
if (!Cot::$usr['isadmin'] || Cot::$cfg['page']['count_admin']) { // Если пользователь не админ или настройка разрешает считать скачивания админами
$pag['page_filecount']++; // Увеличиваем счётчик скачиваний
$sql_page_update = Cot::$db->query("UPDATE $db_pages SET page_filecount=page_filecount+1 WHERE page_id=".$id); // Обновление счётчика скачиваний в базе данных
}
$redir = (preg_match('#^(http|ftp)s?://#', $pag['page_url']) ? '' : COT_ABSOLUTE_URL) . $pag['page_url']; // Формируем URL для редиректа на файл
header('Location: ' . $redir); // Выполняем редирект на файл
echo cot_rc('page_code_redir'); // Выводим сообщение о редиректе
exit; // Завершаем выполнение скрипта
}
$pageHasMessages = cot_check_messages(); // Проверка наличия сообщений на странице (например, ошибок или уведомлений)
$pageStaticCacheEnabled = Cot::$cache
&& Cot::$usr['id'] === 0 // Если пользователь не авторизован
&& Cot::$cfg['cache_page'] // Если кэширование страниц включено в настройках
&& !$pageHasMessages // Если на странице нет сообщений
&& (!isset(Cot::$cfg['cache_page_blacklist']) || !in_array($pag['page_cat'], Cot::$cfg['cache_page_blacklist'])); // Если категория страницы не в черном списке для кэширования
// Page views counter
if (!Cot::$usr['isadmin'] || Cot::$cfg['page']['count_admin']) { // Если пользователь не является администратором или администраторы могут учитывать просмотры
if (!$pageStaticCacheEnabled) { // Если кэширование страницы не активно
$pag['page_count']++; // Увеличиваем счетчик просмотров страницы
Cot::$db->update(
Cot::$db->pages, // Обновление таблицы страниц
['page_count' => $pag['page_count']], // Установка нового значения счетчика просмотров
'page_id = ?', // Условие обновления по ID страницы
$pag['page_id'] // ID страницы
);
} else {
Resources::embedFooter( // Вставка в футер для динамического увеличения счетчика просмотров через JavaScript
'fetch("' . cot_url(
'page',
['e' => 'page', 'm' => 'counter', 'a' => 'views', 'id' => $pag['page_id']], // Формирование URL для увеличения счетчика
'',
true
) . '")'
);
}
}
if ($pag['page_cat'] == 'system') { // Если категория страницы равна "system"
Cot::$out['subtitle'] = empty($pag['page_metatitle']) ? $pag['page_title'] : $pag['page_metatitle']; // Если мета-заголовок страницы пустой, то используем обычный заголовок, иначе используем мета-заголовок
} else {
$title_params = array(
'TITLE' => empty($pag['page_metatitle']) ? $pag['page_title'] : $pag['page_metatitle'], // Мета-заголовок или обычный заголовок
'CATEGORY' => $cat['title'] // Название категории страницы
);
Cot::$out['subtitle'] = cot_title(Cot::$cfg['page']['title_page'], $title_params); // Формирование подзаголовка страницы с использованием заданного шаблона
}
Cot::$out['desc'] = empty($pag['page_metadesc']) ? strip_tags($pag['page_desc']) : strip_tags($pag['page_metadesc']); // Установка мета-описания страницы: если мета-описание пустое, используем описание страницы
Cot::$out['keywords'] = !empty($pag['page_keywords']) ? strip_tags($pag['page_keywords']) : ''; // Установка мета-ключевых слов страницы, если они заданы
// Building the canonical URL
$pageurl_params = array('c' => $pag['page_cat']); // Параметры URL для страницы: категория страницы
empty($al) ? $pageurl_params['id'] = $id : $pageurl_params['al'] = $al; // Если алиас страницы пустой, используем ID страницы, иначе - алиас
if ($pg > 0) { // Если номер страницы больше нуля (пагинация)
$pageurl_params['pg'] = $pg; // Добавляем параметр пагинации в URL
}
Cot::$out['canonical_uri'] = cot_url('page', $pageurl_params); // Генерация канонического URL страницы с учетом всех параметров
$mskin = cot_tplfile(array('page', $cat['tpl'])); // Загрузка шаблона страницы в зависимости от категории (пользовательский шаблон категории)
Cot::$env['last_modified'] = $pag['page_updated']; // Установка времени последнего обновления страницы
/* === Hook === */
foreach (cot_getextplugins('page.main') as $pl) { // Подключение плагинов, если они есть для обработки страницы
include $pl; // Включение каждого плагина для обработки
}
/* ============ */
if ($pag['page_file']) { // Если страница имеет файл, связанный с ней
unset($_SESSION['dl']); // Удаляем предыдущий идентификатор скачивания из сессии
$_SESSION['dl'] = $id; // Устанавливаем идентификатор страницы как текущий для скачивания
}
require_once Cot::$cfg['system_dir'] . '/header.php'; // Подключение заголовка сайта
require_once cot_incfile('users', 'module'); // Подключение модуля пользователей для дальнейшей работы с пользователями
$t = new XTemplate($mskin); // Создание нового экземпляра шаблона XTemplate с указанным шаблоном страницы
$t->assign( // Присваивание данных шаблону для отображения
cot_generate_pagetags( // Генерация тэгов для страницы
$pag,
'PAGE_',
0,
Cot::$usr['isadmin'],
Cot::$cfg['homebreadcrumb'],
'',
$pag['page_pageurl']
)
);
$t->assign('PAGE_OWNER', cot_build_user($pag['page_ownerid'], $pag['user_name'])); // Присваивание информации о владельце страницы
$t->assign(cot_generate_usertags($pag, 'PAGE_OWNER_')); // Присваивание тэгов пользователя, связанные с владельцем страницы
$pag['page_file'] = intval($pag['page_file']); // Преобразование значения поля page_file в целое число (тип данных)
if ($pag['page_file'] > 0) { // Если существует файл, связанный с этой страницей
if (Cot::$sys['now'] > $pag['page_begin']) { // Если текущая дата позже даты начала действия страницы
if (!empty($pag['page_url'])) { // Если указан URL файла
$dotpos = mb_strrpos($pag['page_url'], ".") + 1; // Находим позицию последней точки в URL (для определения расширения файла)
$type = mb_strtolower(mb_substr($pag['page_url'], $dotpos, 5)); // Извлекаем расширение файла и приводим к нижнему регистру
$pag['page_fileicon'] = cot_rc('page_icon_file_path'); // Устанавливаем путь к иконке для файла
if (!file_exists($pag['page_fileicon'])) { // Если иконка не существует
$pag['page_fileicon'] = cot_rc('page_icon_file_default'); // Используем иконку по умолчанию
}
$pag['page_fileicon'] = cot_rc('page_icon_file', ['icon' => $pag['page_fileicon']]); // Генерация иконки с помощью cot_rc
} else {
$pag['page_fileicon'] = ''; // Если URL файла пустой, иконка не задается
}
$t->assign([ // Присваивание данных шаблону
'PAGE_FILE_SIZE' => $pag['page_size'] / 1024, // Размер файла в KiB (устаревшее, но сохраняется для совместимости)
'PAGE_FILE_SIZE_BYTES' => $pag['page_size'], // Размер файла в байтах
'PAGE_FILE_SIZE_READABLE' => cot_build_filesize($pag['page_size'], 1), // Читаемый размер файла
'PAGE_FILE_COUNT' => $pag['page_filecount'], // Количество скачиваний файла
'PAGE_FILE_ICON' => $pag['page_fileicon'], // Иконка файла
'PAGE_FILE_NAME' => basename($pag['page_url']), // Имя файла (из URL)
'PAGE_FILE_COUNTTIMES' => cot_declension($pag['page_filecount'], $Ls['Times']), // Число скачиваний с учетом склонений
]);
if (($pag['page_file'] === 2 && Cot::$usr['id'] == 0) || ($pag['page_file'] === 2 && !Cot::$usr['auth_download'])) { // Если файл доступен только для зарегистрированных пользователей или тех, кто имеет права на скачивание
$t->assign([ // Присваивание данных для шаблона (если файл доступен только для регистрации)
'PAGE_FILETITLE' => Cot::$L['Members_download'], // Заголовок для файла
'PAGE_FILE_URL' => cot_url('users', 'm=register'), // Ссылка на страницу регистрации
]);
} else { // Если файл доступен для скачивания
$t->assign([ // Присваивание данных для шаблона (если файл доступен для скачивания)
'PAGE_FILETITLE' => $pag['page_title'], // Заголовок для файла
'PAGE_FILE_URL' => cot_url('page', array('c' => $pag['page_cat'], 'id' => $id, 'a' => 'dl')), // Ссылка на скачивание файла
]);
}
}
}
// Multi tabs
$pag['page_tabs'] = explode('[[ newpage ]]', $t->vars['PAGE_TEXT'], 99); // Разделение содержимого страницы на вкладки по метке [[ newpage ]]
$pag['page_totaltabs'] = count($pag['page_tabs']); // Количество вкладок
if ($pag['page_totaltabs'] > 1) { // Если существует больше одной вкладки
if (empty($pag['page_tabs'][0])) { // Если первая вкладка пуста
$remove = array_shift($pag['page_tabs']); // Удаляем первую пустую вкладку
$pag['page_totaltabs']--; // Уменьшаем количество вкладок
}
$max_tab = $pag['page_totaltabs'] - 1; // Максимальный индекс вкладки
$pag['page_tab'] = ($pag['page_tab'] > $max_tab) ? 0 : $pag['page_tab']; // Если текущий индекс вкладки больше максимального, сбрасываем на первую вкладку
$pag['page_tabtitles'] = array(); // Массив для заголовков вкладок
for ($i = 0; $i < $pag['page_totaltabs']; $i++) { // Перебор всех вкладок
if (mb_strpos($pag['page_tabs'][$i], '<br />') === 0) { // Если вкладка начинается с <br />
$pag['page_tabs'][$i] = mb_substr($pag['page_tabs'][$i], 6); // Убираем <br /> с начала текста вкладки
}
$p1 = mb_strpos($pag['page_tabs'][$i], '[title]'); // Поиск метки [title]
$p2 = mb_strpos($pag['page_tabs'][$i], '[/title]'); // Поиск метки [/title]
if ($p2 > $p1 && $p1 < 4) { // Если обе метки найдены и [title] раньше чем 4 символа
$pag['page_tabtitle'][$i] = mb_substr($pag['page_tabs'][$i], $p1 + 7, ($p2 - $p1) - 7); // Извлекаем заголовок вкладки
if ($i == $pag['page_tab']) { // Если это текущая вкладка
$pag['page_tabs'][$i] = trim(str_replace('[title]'.$pag['page_tabtitle'][$i].'[/title]', '', $pag['page_tabs'][$i])); // Убираем метки [title] из текста вкладки
}
} else {
$pag['page_tabtitle'][$i] = $i == 0 ? $pag['page_title'] : Cot::$L['Page'] . ' ' . ($i + 1); // Если меток нет, задаем стандартный заголовок
}
// Формирование URL для вкладки
$tab_url = empty($al)
? cot_url('page', 'c='.$pag['page_cat'].'&id='.$id.'&pg='.$i) // URL с параметрами для вкладки
: cot_url('page', 'c='.$pag['page_cat'].'&al='.$al.'&pg='.$i);
// Генерация ссылки на вкладку
$pag['page_tabtitles'][] .= cot_rc_link($tab_url, ($i+1).'. '.$pag['page_tabtitle'][$i],
array('class' => 'page_tabtitle')); // Составление ссылки для вкладки
$pag['page_tabs'][$i] = str_replace('[[ newpage ]]', '', $pag['page_tabs'][$i]); // Убираем метки [[ newpage ]]
$pag['page_tabs'][$i] = preg_replace('#^(<br />)+#', '', $pag['page_tabs'][$i]); // Убираем лишние <br /> в начале текста
$pag['page_tabs'][$i] = trim($pag['page_tabs'][$i]); // Очищаем текст от лишних пробелов
}
$pag['page_tabtitles'] = implode('<br />', $pag['page_tabtitles']); // Склеиваем все ссылки на вкладки в одну строку
$pag['page_text'] = $pag['page_tabs'][$pag['page_tab']]; // Текст текущей вкладки
// Temporarily disable easypagenav to allow 0-based numbers
$tmp = Cot::$cfg['easypagenav']; // Сохраняем текущие настройки навигации
Cot::$cfg['easypagenav'] = false; // Отключаем easypagenav для корректного отображения номеров страниц с нуля
$pn = cot_pagenav('page', (empty($al) ? 'id='.$id : 'al='.$al), $pag['page_tab'], $pag['page_totaltabs'], 1, 'pg'); // Создание навигации по вкладкам
$pag['page_tabnav'] = $pn['main']; // Сохранение основной части навигации
Cot::$cfg['easypagenav'] = $tmp; // Восстанавливаем исходные настройки
// Присваиваем данные шаблону
$t->assign([
'PAGE_MULTI_TABNAV' => $pag['page_tabnav'], // Навигация между вкладками
'PAGE_MULTI_TABTITLES' => $pag['page_tabtitles'], // Заголовки всех вкладок
'PAGE_MULTI_CURTAB' => $pag['page_tab'] + 1, // Индекс текущей вкладки (сдвиг на 1 для отображения)
'PAGE_MULTI_MAXTAB' => $pag['page_totaltabs'], // Общее количество вкладок
'PAGE_TEXT' => $pag['page_text'], // Текст текущей вкладки
]);
$t->parse('MAIN.PAGE_MULTI'); // Отображение блока с вкладками
}
// Error and message handling
cot_display_messages($t); // Выводит сообщения об ошибках или уведомления на страницу
/* === Hook === */
foreach (cot_getextplugins('page.tags') as $pl) { // Подключение расширений, связанных с тэгами страницы
include $pl; // Подключаем каждый плагин
}
/* ===== */
if (Cot::$usr['isadmin'] || Cot::$usr['id'] == $pag['page_ownerid']) { // Если пользователь администратор или является владельцем страницы
$t->parse('MAIN.PAGE_ADMIN'); // Парсинг и вывод блока с административными опциями
}
if (($pag['page_file'] == 2 && Cot::$usr['id'] == 0) || ($pag['page_file'] == 2 && !Cot::$usr['auth_download'])) { // Если файл доступен только зарегистрированным пользователям или если пользователь не авторизован для скачивания
$t->parse('MAIN.PAGE_FILE.MEMBERSONLY'); // Парсинг и вывод блока "Только для членов"
} else {
$t->parse('MAIN.PAGE_FILE.DOWNLOAD'); // Парсинг и вывод блока для скачивания файла
}
if (!empty($pag['page_url'])) { // Если указана URL-адрес страницы
$t->parse('MAIN.PAGE_FILE'); // Парсинг и вывод блока с файлом
}
$t->parse('MAIN'); // Завершающий парсинг основного блока страницы
$t->out('MAIN'); // Вывод итогового результата
require_once Cot::$cfg['system_dir'] . '/footer.php'; // Подключение футера сайта
if ($pageStaticCacheEnabled) { // Если включено кэширование статического контента
Cot::$cache->static->write(); // Записываем в кэш статическое содержимое страницы
}