$sql_forums = Cot::$db->query("SELECT * FROM $db_forum_topics WHERE ft_id= $q"); // Выполняется запрос в базу данных для получения информации о теме с ID $q из таблицы $db_forum_topics.
if ($rowt = $sql_forums->fetch()) { // Если запрос возвращает данные и тема с ID $q существует, то выполняется следующий блок.
if ($rowt['ft_mode'] == 1 && !(Cot::$usr['isadmin'] || $rowt['ft_firstposterid'] == Cot::$usr['id'])) { // Если режим темы (ft_mode) равен 1, и пользователь не является администратором, а также не является автором первого поста в теме, то:
cot_die(); // Останавливаем выполнение скрипта и завершаем выполнение, так как у пользователя нет прав на доступ к теме.
}
} else {
cot_die(true, true); // Если тема с ID $q не найдена, то выполняется завершение работы скрипта с ошибкой (true, true) — для безопасного завершения.
}
Пояснение:
-
Запрос в базу данных: Запрос выбирает все данные из таблицы тем форума
$db_forum_topics, гдеft_idсоответствует ID темы$q. -
Проверка существования темы: После выполнения запроса и получения данных с помощью метода
fetch(), если тема найдена, выполняется проверка её режима (ft_mode). -
Проверка прав доступа: Если тема находится в специальном режиме (
ft_mode == 1), то доступ к теме разрешается только администратору или пользователю, который является автором первого поста в теме ($rowt['ft_firstposterid'] == Cot::$usr['id']). В противном случае выполняется завершение работы скрипта с помощьюcot_die(), что препятствует доступу к теме. -
Обработка ошибки: Если тема с указанным ID не существует в базе данных, вызывается
cot_die(true, true), что завершает выполнение скрипта и возвращает ошибку.
$sql_forums = Cot::$db->query("UPDATE $db_forum_topics SET ft_viewcount=ft_viewcount+1 WHERE ft_id = $q");
// Выполняется обновление таблицы $db_forum_topics: увеличивается счетчик просмотров (ft_viewcount) для темы с ID $q.
$sql_forums = Cot::$db->query("UPDATE $db_forum_stats SET fs_viewcount=fs_viewcount+1 WHERE fs_cat = " . Cot::$db->quote($s));
// Выполняется обновление таблицы $db_forum_stats: увеличивается общий счетчик просмотров (fs_viewcount) для категории форума, идентификатор которой соответствует $s.
// Используется метод Cot::$db->quote() для экранирования переменной $s и защиты от SQL инъекций.
$where['topicid'] = "fp_topicid = $q";
// Создается ассоциативный массив $where, где ключ 'topicid' соответствует условию фильтрации постов по теме с ID $q.
$order = 'fp_id ASC';
// Переменной $order присваивается строка 'fp_id ASC', которая будет использоваться для сортировки постов по возрастанию их ID (посты будут отображаться в порядке их создания).
$join_columns = '';
// Инициализация переменной $join_columns пустой строкой. Она предназначена для хранения списка колонок, которые могут быть использованы при объединении таблиц (JOIN) в запросах.
$join_condition = '';
// Инициализация переменной $join_condition пустой строкой. Она будет хранить условия для объединения таблиц, если это потребуется.
Пояснение:
-
Обновление счетчиков просмотров:
- В первом запросе обновляется количество просмотров темы (
ft_viewcount) для темы с заданным ID. - Во втором запросе обновляется общий счетчик просмотров категории форума (
fs_viewcount), для чего используется экранированное значение переменной$s, чтобы предотвратить SQL-инъекции.
- В первом запросе обновляется количество просмотров темы (
-
Фильтрация и сортировка:
- Переменная
$whereиспользуется для хранения условия фильтрации постов по заданной теме$q. - Переменная
$orderбудет использоваться для сортировки результатов по возрастанию ID постов.
- Переменная
-
Готовность к объединению таблиц:
- Переменные
$join_columnsи$join_conditionмогут быть использованы для подготовки сложных запросов с объединением нескольких таблиц (JOIN). На данный момент они пустые и могут быть заполнены в дальнейшем в коде, если потребуется выполнить такие запросы.
- Переменные
if (!empty($p))
// Проверка, если переменная $p не пуста, то есть если ID поста ($p) передан в запрос.
{
$p_id = $p;
// Присваиваем значению переменной $p значение ID поста ($p).
$postsbefore = Cot::$db->query("SELECT COUNT(*) FROM $db_forum_posts AS p $join_condition WHERE " . implode(' AND ', $where) . " AND fp_id < $p_id")->fetchColumn();
// Выполняем запрос к базе данных для подсчета количества постов перед текущим постом ($p_id).
// Используется объединение условий фильтрации из массива $where (с помощью implode) и дополнительные условия объединения таблиц (если они заданы в $join_condition).
// Результат — количество постов, чей ID меньше, чем $p_id.
$d = Cot::$cfg['forums']['maxpostsperpage'] * floor($postsbefore / Cot::$cfg['forums']['maxpostsperpage']);
// Переменной $d присваиваем количество постов, которые должны быть отображены на странице перед текущим постом.
// Это вычисляется как максимальное количество постов на странице (maxpostsperpage) умноженное на количество полных страниц, которые могут быть перед этим постом.
$durl = Cot::$cfg['easypagenav'] ? floor($d / Cot::$cfg['forums']['maxpostsperpage']) + 1 : $d;
// Если включен параметр 'easypagenav' (пользовательский интерфейс для навигации), то $durl будет номером страницы, на которой находится текущий пост.
// Если 'easypagenav' отключен, то используется значение $d (количество постов до текущего).
}
if (!empty($id))
// Проверка, если переменная $id не пуста, то есть если ID конкретного поста ($id) передан в запрос.
{
$where['id'] = "fp_id = $id";
// В массив $where добавляется условие для фильтрации постов по конкретному ID поста ($id).
}
foreach (cot_getextplugins('forums.posts.query') as $pl)
// Выполняется цикл по всем подключаемым плагинам для обработки запроса. С помощью этой функции можно добавить дополнительную логику.
{
include $pl;
// Подключаем каждый плагин, который будет работать с запросом постов.
}
Пояснение:
-
Переменная
$p:- Когда задан ID поста (
$p), выполняется запрос для подсчета количества постов перед этим постом. - Это нужно, чтобы правильно вычислить, сколько постов нужно пропустить до текущей страницы (для пагинации). В результате вычисляется переменная
$d, которая указывает, сколько постов следует отобразить до текущего поста на предыдущих страницах. - Если активирован параметр
easypagenav, то определяется номер страницы, на которой находится текущий пост.
- Когда задан ID поста (
-
Переменная
$id:- Если передан конкретный ID поста, добавляется условие фильтрации для выбора поста с таким ID в массив
$where.
- Если передан конкретный ID поста, добавляется условие фильтрации для выбора поста с таким ID в массив
-
Плагины:
- В конце выполняется цикл по плагинам, связанным с запросом к постам, с помощью функции
cot_getextplugins. Это позволяет гибко расширять функциональность сайта через плагины, изменяя логику работы с запросами к постам.
- В конце выполняется цикл по плагинам, связанным с запросом к постам, с помощью функции
$where = array_diff($where, array(''));
// Функция array_diff удаляет все пустые значения из массива $where. Это необходимо для того, чтобы избежать условий с пустыми значениями в запросах, которые могут привести к некорректному выполнению SQL-запроса.
$totalposts = Cot::$db->query("SELECT COUNT(*) FROM $db_forum_posts AS p $join_condition WHERE " . implode(' AND ', $where))->fetchColumn();
// Выполняется запрос к базе данных, который подсчитывает общее количество постов, соответствующих условиям в массиве $where (с учетом всех добавленных фильтров).
// Запрос использует функцию `implode`, чтобы преобразовать массив условий в строку, разделенную "AND".
// Disallow accessing non-existent pages
if (empty($id) && $totalposts > 0 && $d > $totalposts) {
// Если ID поста не задан и общее количество постов больше нуля, но количество постов, которые должны быть на текущей странице ($d), больше, чем общее количество постов в базе данных,
// это значит, что такая страница не существует.
cot_die_message(404);
// Выводится ошибка "404 Not Found", что означает, что страница не существует (пользователь пытается получить доступ к несуществующей странице).
}
$orderlimit = empty($id) ? " ORDER BY $order LIMIT $d, " . Cot::$cfg['forums']['maxpostsperpage'] : '';
// Если переменная $id не пуста (то есть, есть конкретный пост), то порядок сортировки и лимит на количество записей не добавляются.
// Если $id пуст, добавляется условие ORDER BY для сортировки по $order и LIMIT для ограничения количества выводимых постов на странице,
// начиная с $d (количество пропущенных постов) и ограничением по максимальному числу постов на странице (maxpostsperpage).
$sql_forums = Cot::$db->query("SELECT p.*, u.* $join_columns
FROM $db_forum_posts AS p LEFT JOIN $db_users AS u ON u.user_id=p.fp_posterid $join_condition
WHERE " . implode(' AND ', $where) . $orderlimit);
// Выполняется основной запрос к базе данных, который извлекает все посты из таблицы $db_forum_posts, а также данные о пользователях из таблицы $db_users (с помощью LEFT JOIN).
// Условия фильтрации для выборки постов берутся из массива $where.
// Добавляется сортировка и ограничение на количество записей для пагинации, если это необходимо.
Пояснение:
-
Удаление пустых значений в фильтре:
- Функция
array_diffудаляет пустые строки из массива$where, чтобы избежать использования пустых условий в SQL-запросах, что могло бы вызвать ошибки.
- Функция
-
Проверка на несуществующие страницы:
- Если количество постов на текущей странице (
$d) больше общего числа постов ($totalposts), происходит завершение выполнения с ошибкой 404, что означает, что запрашиваемая страница не существует.
- Если количество постов на текущей странице (
-
Определение лимита и порядка сортировки:
- Если передан конкретный пост ($id), сортировка и лимит пропускаются. Если пост не передан, используется сортировка и лимит для отображения нужных постов на странице с учетом пагинации.
-
Основной запрос:
- Основной SQL-запрос выполняется для выборки постов, а также данных пользователей, оставивших эти посты. Запрос использует фильтрацию, сортировку и пагинацию, если это необходимо.
$title_params = array(
// Создаем массив параметров для заголовка страницы форума.
'FORUM' => Cot::$L['Forums'],
// Название форума из локализованного массива Cot::$L.
'SECTION' => Cot::$structure['forums'][$s]['title'],
// Заголовок раздела форума, который определяется по ключу $s (раздел форума).
'TITLE' => $rowt['ft_title']
// Заголовок темы форума, полученный из строки $rowt (содержит данные о теме форума).
);
$out['subtitle'] = cot_title(Cot::$cfg['forums']['title_posts'], $title_params);
// Генерируется подзаголовок страницы с помощью функции cot_title(), которая формирует строку заголовка с учетом шаблона и переданных параметров.
$out['desc'] = htmlspecialchars(strip_tags($rowt['ft_desc']));
// Описание темы форума обрабатывается для предотвращения выполнения HTML-кода (strip_tags удаляет теги, а htmlspecialchars экранирует специальные символы).
$topicurl_params = array(
// Создаем массив параметров для формирования URL темы форума.
'm' => 'posts',
// Указываем модуль "posts" для ссылок на посты форума.
'q' => $q
// Добавляем параметр для идентификатора темы форума (ID темы).
);
if (($durl > 1 && Cot::$cfg['easypagenav']) || ($durl > 0 && !Cot::$cfg['easypagenav'])) {
// Если активирована пагинация (easypagenav), добавляется параметр для номера страницы (durl).
$topicurl_params['d'] = $durl;
// Параметр 'd' задает номер страницы, если пагинация активирована.
}
Cot::$out['canonical_uri'] = cot_url('forums', $topicurl_params);
// Устанавливаем канонический URL для текущей страницы форума, что помогает поисковым системам избежать дублирования контента.
/* === Hook === */
// Программный хук для возможности подключения сторонних плагинов.
foreach (cot_getextplugins('forums.posts.main') as $pl) {
// Перебор всех подключенных плагинов для данного хука.
include $pl;
// Включение каждого плагина в код.
}
/* ===== */
require_once Cot::$cfg['system_dir'] . '/header.php';
// Подключение файла заголовка системы для корректного отображения страницы.
Пояснение:
-
Формирование заголовка страницы:
- В массиве
$title_paramsсобираются данные, которые будут использоваться для создания подзаголовка страницы. Используется функцияcot_title()для формирования строки с подзаголовком, основанной на конфигурации форума.
- В массиве
-
Очищение и экранирование описания:
- В строке описания темы удаляются все HTML-теги и экранируются специальные символы, чтобы предотвратить выполнение вредоносного кода.
-
Формирование URL:
- В массиве
$topicurl_paramsсобираются параметры для генерации URL страницы форума, включая параметры пагинации (если нужно).
- В массиве
-
Канонический URL:
- Канонический URL необходим для SEO, чтобы указать поисковым системам на основной URL страницы, исключая возможные дубли с другими параметрами.
-
Хук для плагинов:
- Перед загрузкой контента подключаются все сторонние плагины, которые могут изменить или добавить функционал в данный участок страницы.
-
Подключение заголовка:
- Подключение файла заголовка системы для корректного отображения страницы форума.
$mskin = cot_tplfile(array('forums', 'posts', Cot::$structure['forums'][$s]['tpl']));
// Определяется путь к шаблону форума для отображения страниц. Здесь используется массив, который включает: 'forums', 'posts', и шаблон для текущего раздела форума из структуры форума (Cot::$structure['forums'][$s]['tpl']).
$t = new XTemplate($mskin);
// Создается новый объект шаблона XTemplate, который будет использовать файл шаблона, определенный в предыдущей строке.
/* === Hook - Part1 : Set === */
// Хук для возможности подключения внешних плагинов, который используется на данном этапе обработки страницы форума.
$extp = cot_getextplugins('forums.posts.loop');
// Получение всех подключенных плагинов для хука 'forums.posts.loop', которые могут изменить или дополнить отображение постов в теме форума.
/* ===== */
// Завершение секции хука.
Пояснение:
-
Загрузка шаблона:
- В строке
$mskin = cot_tplfile(array('forums', 'posts', Cot::$structure['forums'][$s]['tpl']));происходит определение пути к шаблону, который будет использоваться для отображения страницы постов форума. Путь строится на основе структуры форума и имени шаблона для текущего раздела.
- В строке
-
Создание объекта шаблона:
- В строке
$t = new XTemplate($mskin);создается объект классаXTemplate, который будет использовать указанный файл шаблона ($mskin) для обработки.
- В строке
-
Хуки для плагинов:
- С помощью хука
cot_getextplugins('forums.posts.loop')на этом этапе можно подключить дополнительные плагины, которые могут взаимодействовать с циклом отображения постов в теме форума, изменяя вывод данных или добавляя дополнительный функционал.
- С помощью хука
$fp_num = 0;
// Инициализация счетчика количества постов (для дальнейшего использования, например, при проверке удаления постов).
foreach ($sql_forums->fetchAll() as $row) {
// Проходим по всем записям (постам), полученным из запроса к базе данных. Для каждого поста выполняются следующие действия.
$row['user_text'] = (Cot::$cfg['forums']['cat_' . $s]['allowusertext']) ? $row['user_text'] : '';
// Если в настройках форума разрешено использование пользовательских текстов для данного раздела (cat_), то оставляем значение из базы, иначе очищаем поле (для предотвращения вывода текста пользователя, если это запрещено).
$row['fp_updatedby'] = '';
// Очищаем поле "fp_updatedby", вероятно, для того чтобы в шаблоне отображалась пустая строка, если пост был обновлен не пользователем, а системой.
$fp_num++;
// Увеличиваем счетчик количества постов.
// Генерация URL для цитирования поста, если пользователь авторизован
$rowquote_url = (Cot::$usr['id'] > 0) ? cot_url('forums', 'm=posts&s=' . $s . '&q=' . $q . '"e=' . $row['fp_id'] . '&d=' . $durl . '&n=last', '#np') : '';
// Формируется URL для цитирования, если пользователь авторизован.
$rowquote = (Cot::$usr['id'] > 0) ? cot_rc('forums_rowquote', array('url' => $rowquote_url)) : '';
// Если пользователь авторизован, генерируется HTML для кнопки цитирования с использованием шаблона 'forums_rowquote', иначе оставляем пустым.
// Генерация URL для редактирования поста
$rowedit_url = ((Cot::$usr['isadmin'] || ($row['fp_posterid'] == Cot::$usr['id'] && (Cot::$cfg['forums']['edittimeout'] == '0' || $sys['now'] - $row['fp_creation'] < Cot::$cfg['forums']['edittimeout'] * 3600))) && Cot::$usr['id'] > 0) ? cot_url('forums', 'm=editpost&s=' . $s . '&q=' . $q . '&p=' . $row['fp_id'] . '&d=' . $durl . '&' . cot_xg()) : '';
// Если пользователь является администратором или автором поста и не прошло время, которое ограничивает редактирование поста, генерируется URL для редактирования поста.
$rowedit = ((Cot::$usr['isadmin'] || ($row['fp_posterid'] == Cot::$usr['id'] && (Cot::$cfg['forums']['edittimeout'] == '0' || $sys['now'] - $row['fp_creation'] < Cot::$cfg['forums']['edittimeout'] * 3600))) && Cot::$usr['id'] > 0) ? cot_rc('forums_rowedit', array('url' => $rowedit_url)) : '';
// Если пользователь авторизован и ему разрешено редактировать пост, генерируется HTML для кнопки редактирования с использованием шаблона 'forums_rowedit'.
// Генерация URL для удаления поста
$rowdelete_url = (Cot::$usr['id'] > 0 && (Cot::$usr['isadmin'] || ($row['fp_posterid'] == Cot::$usr['id'] && (Cot::$cfg['forums']['edittimeout'] == '0' || $sys['now'] - $row['fp_creation'] < Cot::$cfg['forums']['edittimeout'] * 3600)))) ? cot_confirm_url(cot_url('forums', 'm=posts&a=delete&' . cot_xg() . '&s=' . $s . '&q=' . $q . '&p=' . $row['fp_id'] . '&d=' . $durl), 'forums', 'forums_confirm_delete_post') : '';
// Если пользователь авторизован и является администратором или автором поста с учетом ограничения по времени редактирования, генерируется URL для подтверждения удаления поста.
$rowdelete = (Cot::$usr['id'] > 0 && (Cot::$usr['isadmin'] || ($row['fp_posterid'] == Cot::$usr['id'] && (Cot::$cfg['forums']['edittimeout'] == '0' || $sys['now'] - $row['fp_creation'] < Cot::$cfg['forums']['edittimeout'] * 3600)) && $fp_num > 1)) ? cot_rc('forums_rowdelete', array('url' => $rowdelete_url)) : '';
// Если пользователь авторизован и имеет право на удаление, а также если в теме есть еще посты (fp_num > 1), генерируется HTML для кнопки удаления поста с использованием шаблона 'forums_rowdelete'.
}
Пояснение:
-
Цитирование поста:
- Если пользователь авторизован, то для каждого поста генерируется возможность цитирования. Это позволяет пользователю ссылаться на конкретные посты для цитирования.
-
Редактирование поста:
- Для каждого поста проверяется, может ли пользователь редактировать его. Это зависит от роли пользователя (администратор или автор поста) и времени, прошедшего с момента создания поста. Если разрешено, генерируется ссылка для редактирования.
-
Удаление поста:
- Для каждого поста генерируется ссылка для его удаления, если пользователь авторизован и имеет соответствующие права. Удалить пост можно, если прошло достаточное время для редактирования и если в теме остались другие посты.
if (!empty($row['fp_updater'])) {
$row['fp_updatedby'] = sprintf(Cot::$L['forums_updatedby'], htmlspecialchars($row['fp_updater']), cot_date('datetime_medium', $row['fp_updated']), cot_build_timegap($row['fp_updated'], $sys['now']));
}
// Если поле 'fp_updater' не пустое (то есть пост был обновлен), создается строка с информацией о том, кто обновил пост.
// В строке будет указано имя пользователя, дата последнего обновления и временной интервал с момента обновления (с использованием функции cot_build_timegap для отображения времени в понятном формате).
if (isset(Cot::$cfg['legacyMode']) && Cot::$cfg['legacyMode']) {
// Проверка, включен ли в конфигурации режим совместимости (legacyMode).
// Если режим включен (например, для поддержки старой версии), выполняется следующее:
// @deprecated in 0.9.24 - данная строка считается устаревшей начиная с версии 0.9.24.
$t->assign(cot_generate_usertags($row, 'FORUMS_POSTS_ROW_USER'));
// Генерируются теги пользователя для вывода в шаблон с использованием функции cot_generate_usertags. Эти теги выводят информацию о пользователе, который создал или обновил пост, в определенном формате.
}
$t->assign(cot_generate_usertags($row, 'FORUMS_POSTS_ROW_USER_'));
// В любом случае, генерируются теги пользователя для вывода в шаблон с более новым идентификатором 'FORUMS_POSTS_ROW_USER_'.
// Это может быть связано с новой системой отображения информации о пользователях в шаблонах.
Пояснение:
-
Отображение информации о последнем обновлении поста:
- Если пост был обновлен (то есть есть значение в поле
fp_updater), то создается строка, которая показывает, кто именно обновил пост, когда это произошло, и сколько времени прошло с момента обновления.
- Если пост был обновлен (то есть есть значение в поле
-
Режим совместимости (legacyMode):
- Если включен режим совместимости (предположительно для поддержки старых версий форума), используется устаревшая функция
cot_generate_usertagsдля вывода информации о пользователе, связанной с постом. Этот функционал считается устаревшим с версии 0.9.24, возможно, для перехода на более новую систему тегов пользователей.
- Если включен режим совместимости (предположительно для поддержки старых версий форума), используется устаревшая функция
-
Генерация тегов пользователя:
- В любом случае генерируются теги пользователя с помощью функции
cot_generate_usertags, но для новых версий форума используется более новый идентификатор 'FORUMS_POSTS_ROW_USER_' для вывода информации о пользователе.
- В любом случае генерируются теги пользователя с помощью функции
$t->assign([
'FORUMS_POSTS_ROW_ID' => $row['fp_id'],
// Идентификатор поста. Это уникальный идентификатор для каждого поста.
'FORUMS_POSTS_ROW_POSTID' => 'post_' . $row['fp_id'],
// Уникальный ID поста, используется для создания CSS-классов или ссылок на конкретный пост.
'FORUMS_POSTS_ROW_IDURL' => cot_url('forums', 'm=posts&id=' . $row['fp_id']),
// URL для перехода непосредственно к данному посту по его ID.
'FORUMS_POSTS_ROW_URL' => cot_url('forums', 'm=posts&q=' . $row['fp_topicid'] . '&d=' . $durl, "#" . $row['fp_id']),
// URL для перехода к посту внутри темы, с возможностью перехода на определенную страницу и с якорем на пост.
'FORUMS_POSTS_ROW_CREATION' => cot_date('datetime_medium', $row['fp_creation']),
// Дата и время создания поста в формате "datetime_medium".
'FORUMS_POSTS_ROW_CREATION_STAMP' => $row['fp_creation'],
// Временная метка создания поста (timestamp).
'FORUMS_POSTS_ROW_UPDATED' => cot_date('datetime_medium', $row['fp_updated']),
// Дата и время последнего обновления поста в формате "datetime_medium".
'FORUMS_POSTS_ROW_UPDATED_STAMP' => $row['fp_updated'],
// Временная метка последнего обновления поста (timestamp).
'FORUMS_POSTS_ROW_UPDATER' => htmlspecialchars($row['fp_updater']),
// Имя пользователя, который обновил пост. Безопасное отображение (escape) для предотвращения XSS-атак.
'FORUMS_POSTS_ROW_UPDATEDBY' => $row['fp_updatedby'],
// Информация о том, кто и когда обновил пост.
'FORUMS_POSTS_ROW_TEXT' => cot_parse($row['fp_text'], (Cot::$cfg['forums']['markup'] && Cot::$cfg['forums']['cat_' . $s]['allowbbcodes'])),
// Основной текст поста, с возможностью обработки разметки (например, BB-коды), если это разрешено в настройках форума.
'FORUMS_POSTS_ROW_ANCHORLINK' => cot_rc('forums_code_post_anchor', array('id' => $row['fp_id'])),
// Ссылка на якорь внутри поста, используется для ссылок, которые ведут к определенному месту на странице.
'FORUMS_POSTS_ROW_POSTERNAME' => cot_build_user($row['fp_posterid'], $row['fp_postername']),
// Имя пользователя, создавшего пост, с использованием функции для генерации тега пользователя (например, ссылки на профиль).
'FORUMS_POSTS_ROW_POSTERID' => $row['fp_posterid'],
// Идентификатор пользователя, создавшего пост.
'FORUMS_POSTS_ROW_POSTERIP' => (Cot::$usr['isadmin']) ? cot_build_ipsearch($row['fp_posterip']) : '',
// IP-адрес создателя поста, если пользователь является администратором.
'FORUMS_POSTS_ROW_DELETE' => $rowdelete,
// Возможность удалить пост, если пользователь имеет соответствующие права.
'FORUMS_POSTS_ROW_DELETE_URL' => $rowdelete_url,
// URL для удаления поста (с подтверждением).
'FORUMS_POSTS_ROW_EDIT' => $rowedit,
// Возможность редактировать пост.
'FORUMS_POSTS_ROW_EDIT_URL' => $rowedit_url,
// URL для редактирования поста.
'FORUMS_POSTS_ROW_QUOTE' => $rowquote,
// Возможность цитировать пост.
'FORUMS_POSTS_ROW_QUOTE_URL' => $rowquote_url,
// URL для цитирования поста.
'FORUMS_POSTS_ROW_BOTTOM' => ((empty($id) ? $d + $fp_num : $id) == $totalposts) ? Cot::$R['forums_code_bottom'] :
((Cot::$usr['id'] > 0 && $n == 'unread' && $row['fp_creation'] > Cot::$usr['lastvisit']) ? Cot::$R['forums_code_unread'] : ''),
// Код для отображения информации внизу поста, если это последний пост или новый пост, который еще не был прочитан пользователем.
'FORUMS_POSTS_ROW_ODDEVEN' => cot_build_oddeven($fp_num),
// Для чередования классов CSS (например, для четных и нечетных строк).
'FORUMS_POSTS_ROW_NUM' => $fp_num,
// Номер текущего поста на странице.
'FORUMS_POSTS_ROW_ORDER' => empty($id) ? $d + $fp_num : $id
// Порядковый номер поста, используется для навигации по страницам.
]);
if (!empty(Cot::$extrafields[Cot::$db->forum_posts])) {
foreach (Cot::$extrafields[Cot::$db->forum_posts] as $exfld) {
$tag = mb_strtoupper($exfld['field_name']);
// Создание тега для поля, преобразованного в верхний регистр.
$exfld_title = cot_extrafield_title($exfld, 'forums_post_');
// Получение заголовка (названия) дополнительного поля, которое будет отображаться в интерфейсе.
$t->assign([
'FORUMS_POSTS_ROW_' . $tag . '_TITLE' => $exfld_title,
// Передаем в шаблон заголовок поля.
'FORUMS_POSTS_ROW_' . $tag => cot_build_extrafields_data('forums', $exfld,
$row['fp_' . $exfld['field_name']],
(Cot::$cfg['forums']['markup'] && Cot::$cfg['forums']['cat_' . $s]['allowbbcodes'])),
// Строим данные для дополнительного поля. Это может быть текст или другие данные, с обработкой разметки, если это разрешено.
'FORUMS_POSTS_ROW_' . $tag . '_VALUE' => $row['fp_' . $exfld['field_name']]
// Передаем значение поля в шаблон.
]);
}
}
Этот код выполняет обработку и отображение дополнительных полей (extrafields) для постов форума. В рамках форума могут быть настроены дополнительные поля, такие как текстовые поля, даты или другие данные, которые могут быть добавлены к постам. В этом коде они извлекаются, форматируются и передаются в шаблон.
Пояснение шагов:
-
Проверка наличия дополнительных полей:
- Код проверяет, есть ли дополнительные поля для постов форума в глобальной переменной
Cot::$extrafields. Если они есть, код продолжает обработку.
- Код проверяет, есть ли дополнительные поля для постов форума в глобальной переменной
-
Цикл по всем дополнительным полям:
- Каждое дополнительное поле обрабатывается в цикле
foreach. Для каждого поля создаются несколько значений:- Тег для поля: используется для именования переменных в шаблоне.
- Заголовок поля: отображаемое название, получаемое через функцию
cot_extrafield_title. - Данные поля: строится значение, которое будет отображаться в шаблоне. Данные могут быть отформатированы (например, через BB-коды, если это разрешено).
- Значение поля: само значение, которое сохраняется в базе данных для этого поля.
- Каждое дополнительное поле обрабатывается в цикле
-
Передача данных в шаблон:
- Для каждого дополнительного поля создаются три переменные, которые передаются в шаблон:
FORUMS_POSTS_ROW_<FIELD_NAME>_TITLE— заголовок поля.FORUMS_POSTS_ROW_<FIELD_NAME>— данные поля (с обработкой разметки).FORUMS_POSTS_ROW_<FIELD_NAME>_VALUE— необработанное значение поля (просто для хранения).
- Для каждого дополнительного поля создаются три переменные, которые передаются в шаблон:
-
Вставка плагинов (если есть):
- Код включает хуки, используя внешние плагины. Это позволяет подключить дополнительные функции или расширения на этой стадии.
-
Разбор шаблона:
- Шаблон
MAIN.FORUMS_POSTS_ROWанализируется и подготавливается к выводу.
- Шаблон
Пример использования:
Если у поста есть дополнительное поле, например, "image_url", это поле будет отображено с заголовком (например, "Image URL") и значением, которое будет передано в шаблон. Разметка может быть применена к текстовым полям, если это разрешено в настройках форума.
Код предназначен для расширяемости, добавляя возможность работы с различными дополнительными полями и их отображением в шаблоне форума.