Файл "forums.editpost.php" в Cotonti

Включает в себя как логику отображения страницы редактирования, так и обработку данных при их изменении и сохранении. предназначен для редактирования уже существующих постов и тем форума

Опубликовано в: Модуль Forums в Cotonti CMF

Описание назначения файла "forums.editpost.php" в Cotonti CMF

Основное назначение файла:
Файл forums.editpost.php является частью системы форума в Cotonti CMF и предназначен исключительно для редактирования уже существующих постов и тем форума. Этот файл не управляет созданием новых тем или постов, а только предоставляет механизм для редактирования контента, который был уже опубликован пользователями форума. Включает в себя как логику отображения страницы редактирования, так и обработку данных при их изменении и сохранении.

Место в системе:
Файл расположен в директории /modules/forums/inc/, которая является частью модуля Forums — одного из стандартных компонентов системы Cotonti, обеспечивающего функциональность для форумов. Модуль форума управляет всеми аспектами форумов на сайте, включая создание и редактирование постов, создание тем, а также взаимодействие с пользователями. Этот файл интегрируется в более широкий контекст работы форума, где основная цель — это управление контентом сообщений.

Взаимодействие файла внутри сайта

  1. Работа с данными из базы:
    Файл взаимодействует с базой данных для извлечения данных о постах и темах форума. Он использует методы для запроса данных о существующих постах и связанных с ними темах, проверяя права пользователя на редактирование и обеспечивая вывод актуальной информации на форме редактирования. Например, для получения данных поста используется запрос к таблице forum_posts, а для темы — к таблице forum_topics.

  2. Проверка прав пользователя:
    Перед тем как предоставить пользователю доступ к редактированию поста или темы, система проверяет, является ли текущий пользователь автором сообщения или администратором. Также существует проверка на время редактирования (пост может быть отредактирован только в пределах установленного времени).

  3. Обработка данных формы редактирования:
    Файл обрабатывает данные, введенные пользователем в форму редактирования (например, текст сообщения и заголовок темы), проверяет их на соответствие минимальным требованиям и сохраняет изменения в базе данных, если все условия выполнены. Это гарантирует, что только корректные данные будут сохранены.

  4. Работа с дополнительными полями (extrafields):
    В зависимости от настроек форума, файл также обрабатывает дополнительные поля, которые могут быть добавлены к теме или посту. Эти поля позволяют расширить функционал форума, например, добавить дополнительные атрибуты к сообщению.

  5. Обновление данных и кэширование:
    После успешного редактирования поста или темы файл очищает кэш страниц форума, чтобы изменения были немедленно отображены на сайте. Это позволяет избежать ситуации, когда пользователь видит старую версию страницы после внесения изменений.

  6. Использование хуков для плагинов:
    В коде присутствуют хуки для интеграции с внешними плагинами, что позволяет расширять функционал системы. Хуки включают:

    • forums.editpost.first — для выполнения действий до основного процесса редактирования.
    • forums.editpost.update.first — перед обновлением данных в базе.
    • forums.editpost.update.done — после завершения редактирования и обновления данных.
    • forums.editpost.tags — для добавления или изменения тегов на странице редактирования.

Переменные, методы, функции и классы

  • $s, $q, $p, $d, $durl — параметры, передаваемые в URL-запросах. Они отвечают за идентификацию форума, темы и поста.
  • Cot::$db — объект базы данных, используемый для запросов к базе данных.
  • cot_import() — функция для получения и фильтрации данных из запроса.
  • cot_check_xg() — функция для проверки безопасности формы и предотвращения CSRF-атак.
  • cot_blockguests() — функция для предотвращения доступа гостям, требуя авторизации для редактирования постов.
  • cot_auth() — функция для проверки прав пользователя на редактирование темы или поста.
  • cot_textarea() — функция для создания текстового поля, в котором пользователь может редактировать текст поста.
  • cot_inputbox() — функция для создания поля ввода текста.
  • cot_error() — функция для генерации сообщений об ошибках, если введенные данные не соответствуют требованиям.
  • cot_extrafield_title() — функция для получения заголовков для дополнительных полей.
  • cot_build_extrafields() — функция для создания дополнительных полей и их отображения в форме редактирования.
  • cot_redirect() — функция для перенаправления пользователя на другую страницу после успешного редактирования.
  • cot_log() — функция для записи событий в журнал безопасности системы.

Суть содержания кода

  1. Загрузка данных:
    Код извлекает данные о посте и теме из базы данных, проверяя, соответствует ли текущий пользователь автору поста или обладает ли правами администратора. Параметры передаются через URL, и на их основе извлекаются данные, которые будут отображаться в форме редактирования.

  2. Проверка прав доступа:
    Важным моментом является проверка прав пользователя на редактирование поста. Если пользователь не является автором поста или администратором, ему будет отказано в редактировании. Также проверяется время редактирования — если оно прошло, редактирование невозможно.

  3. Обработка данных формы:
    Когда пользователь редактирует пост, код проверяет введенные данные на соответствие минимальным требованиям (например, минимальная длина текста сообщения). В случае ошибок генерируются соответствующие сообщения, и форма повторно отображается с ошибками.

  4. Сохранение изменений:
    После успешной проверки данных, изменения сохраняются в базе данных. Если изменяется заголовок темы, обновляются соответствующие данные в таблице forum_topics. Также, если пост был первым в теме, он обновляет превью темы.

  5. Работа с дополнительными полями:
    В файле также реализована логика работы с дополнительными полями (extrafields), которые могут быть привязаны к посту. Эти поля создаются и отображаются в форме редактирования для каждого поля форума или поста, если таковые есть.

  6. Перенаправление и кэширование:
    После успешного редактирования происходит перенаправление на страницу форума, где были внесены изменения. Также очищается кэш страниц форума, чтобы отобразить актуальные данные.

Заключение

Файл forums.editpost.php — это компонент системы Cotonti CMF, предназначенный исключительно для редактирования постов и тем форума. Он обеспечивает функциональность для редактирования контента, а также включает логику проверки прав пользователя, работы с дополнительными полями и управления безопасностью.

 

// Определение параметра $s, который представляет собой идентификатор категории форума, получаемого из GET-запроса (параметр 's').
$s = cot_import('s', 'G', 'TXT'); // section cat

// Определение параметра $q, который представляет собой идентификатор темы, получаемого из GET-запроса (параметр 'q').
$q = cot_import('q', 'G', 'INT');  // Topic id

// Определение параметра $p, который представляет собой идентификатор сообщения, получаемого из GET-запроса (параметр 'p').
$p = cot_import('p', 'G', 'INT'); // Post id

// Определение переменных для пагинации, которые получают значения из параметров запроса и настроек конфигурации.
[$pg, $d, $durl] = cot_import_pagenav('d', Cot::$cfg['forums']['maxpostsperpage']); // Пагинация постов на странице

/* === Hook === */
// Загружаются дополнительные плагины для расширения функционала на стадии перед основным кодом
foreach (cot_getextplugins('forums.editpost.first') as $pl) { 
	include $pl; // Включаем каждый плагин
}
/* ===== */

// Блокирует доступ для гостей, если это не разрешено в конфигурации.
cot_blockguests();

// Проверка действительности токена для защиты от CSRF атак.
cot_check_xg();

// Проверка существования указанной категории форума, если категории не существует - остановка выполнения сценария.
isset(Cot::$structure['forums'][$s]) || cot_die(); 

 

// Запрос к базе данных для получения поста с указанным id, id темы и категории форума.
$sql_forums = Cot::$db->query(
    'SELECT * FROM ' . Cot::$db->forum_posts . ' WHERE fp_id = ? and fp_topicid = ? and fp_cat = ?',
	[$p, $q, $s] // Параметры: id сообщения, id темы и категория форума
);

// Проверка наличия поста с указанными параметрами.
if ($rowpost = $sql_forums->fetch()) { 
	// Получение прав доступа пользователя к текущей категории форума: чтение, написание и админские права.
	[Cot::$usr['auth_read'], Cot::$usr['auth_write'], Cot::$usr['isadmin']] = cot_auth('forums', $s);

	/* === Hook === */
	// Загружаются плагины для проверки прав на редактирование поста.
	foreach (cot_getextplugins('forums.editpost.rights') as $pl) {
		include $pl; // Включаем каждый плагин
	}
	/* ===== */

	// Проверка прав пользователя на редактирование поста:
	// 1. Если пользователь не является администратором
	// 2. Если пользователь не является автором поста
	// 3. Если прошло слишком много времени с момента создания поста (время ограничено настройкой edittimeout)
	if (
        !Cot::$usr['isadmin'] // Не админ
        && (
            $rowpost['fp_posterid'] != Cot::$usr['id'] // Если пользователь не автор сообщения
            || (Cot::$cfg['forums']['edittimeout'] != '0' && Cot::$sys['now'] - $rowpost['fp_creation'] > Cot::$cfg['forums']['edittimeout'] * 3600) // Или прошло больше времени, чем разрешено на редактирование
        )
    ) {
		// Логирование несанкционированной попытки редактирования поста.
		cot_log('Attempt to edit a post without rights', 'sec', 'forums', 'error');
		// Завершаем выполнение, если нет прав.
		cot_die();
	}
	// Блокируем доступ на чтение, если нет соответствующих прав.
	cot_block(Cot::$usr['auth_read']);
} else {
	// Завершаем выполнение, если пост не найден.
	cot_die();
}

 

// Проверка, является ли редактируемый пост первым в теме.
// Сравниваем id текущего поста с первым постом в теме по id темы.
$isFirstPost = $p == Cot::$db->query("SELECT fp_id FROM $db_forum_posts WHERE fp_topicid = ? ORDER BY fp_id ASC LIMIT 1", [$q])->fetchColumn();

// Запрос к базе данных для получения состояния, режима, заголовка и описания темы форума по id темы.
$sql_forums = Cot::$db->query("SELECT ft_state, ft_mode, ft_title, ft_desc FROM $db_forum_topics WHERE ft_id = $q LIMIT 1");

// Проверка, существует ли тема с данным id.
if ($rowt = $sql_forums->fetch()) {
	// Если тема находится в закрытом состоянии и пользователь не является администратором, прекращаем выполнение.
	if ($rowt['ft_state'] && !Cot::$usr['isadmin']) { 
		cot_die_message(603, true); // Сообщение о закрытой теме
	}
} else {
	// Если тема не найдена, завершаем выполнение.
	cot_die(true, true);
}
// Если переменная $a равна 'update', значит, выполняется процесс обновления поста.
if ($a == 'update') {
	/* === Хук === */
	// Включаем все внешние плагины, зарегистрированные для события 'forums.editpost.update.first'.
	foreach (cot_getextplugins('forums.editpost.update.first') as $pl)
	{
		include $pl;
	}
	/* ===== */

	// Импортируем и очищаем данные для заголовка темы.
	$rtopic['ft_title'] = cot_import('rtopictitle', 'P', 'TXT', 255); // Заголовок темы
	$rtopic['ft_desc'] = cot_import('rtopicdesc', 'P', 'TXT', 255); // Описание темы

	// Инициализация массива для данных поста.
	$rmsg = [];
	// Импортируем и очищаем текст поста.
	$rmsg['fp_text'] = cot_import('rmsgtext', 'P', 'HTM'); // Текст сообщения
    // Если текст сообщения пуст, присваиваем ему пустую строку.
    if (empty($rmsg['fp_text'])) {
        $rmsg['fp_text'] = '';
    }

	// Если пост был написан пользователем, который редактирует его, и прошло менее 5 минут с последнего обновления, 
	// то оставляем поле fp_updater пустым, иначе присваиваем имя текущего пользователя.
	$rmsg['fp_updater'] = (
        $rowpost['fp_posterid'] == Cot::$usr['id'] // Проверка, является ли пользователь автором поста
        && (Cot::$sys['now'] < $rowpost['fp_updated'] + 300) // Проверка, не прошло ли 5 минут с последнего обновления
        && empty($rowpost['fp_updater']) // Проверка, что поле fp_updater еще не установлено
    ) ? '' : Cot::$usr['name']; // Присваиваем имя текущего пользователя, если условия не выполняются

	// Обновляем время последнего изменения поста.
	$rmsg['fp_updated'] = Cot::$sys['now'];

 

// Если заголовок темы был отправлен через форму, но его длина меньше минимально допустимой длины,
// то генерируется ошибка 'forums_titletooshort' для поля 'rtopictitle'.
if (isset($_POST['rtopictitle']) && mb_strlen($rtopic['ft_title']) < Cot::$cfg['forums']['mintitlelength']) {
	cot_error('forums_titletooshort', 'rtopictitle');
}

// Если длина текста сообщения меньше минимально допустимой длины,
// то генерируется ошибка 'forums_messagetooshort' для поля 'rmsgtext'.
if (mb_strlen($rmsg['fp_text']) < Cot::$cfg['forums']['minpostlength']) {
	cot_error('forums_messagetooshort', 'rmsgtext');
}

// Если есть дополнительные поля для тем (extrafields) в настройках форума,
// то для каждого такого поля выполняется импорт его значения и привязка к теме.
if (!empty(Cot::$extrafields[Cot::$db->forum_topics])) {
    foreach (Cot::$extrafields[Cot::$db->forum_topics] as $exfld) {
        // Импортируем значение дополнительного поля для темы, используя функцию cot_import_extrafields.
        // Значение будет сохранено в массиве $rtopic с соответствующим ключом.
        $rtopic['ft_' . $exfld['field_name']] = cot_import_extrafields('rtopic' . $exfld['field_name'], $exfld, 'P', '', 'forums_topic_');
    }
}

// Если есть дополнительные поля для постов (extrafields) в настройках форума,
// то для каждого такого поля выполняется импорт его значения и привязка к сообщению.
if (!empty(Cot::$extrafields[Cot::$db->forum_posts])) {
    foreach (Cot::$extrafields[Cot::$db->forum_posts] as $exfld) {
        // Импортируем значение дополнительного поля для поста, используя функцию cot_import_extrafields.
        // Значение будет сохранено в массиве $rmsg с соответствующим ключом.
        $rmsg['fp_'.$exfld['field_name']] = cot_import_extrafields('rmsg'.$exfld['field_name'], $exfld, 'P', '', 'forums_post_');
    }
}

 

// Проверяем, если в процессе обработки формы не было найдено ошибок.
if (!cot_error_found()) {
    // Если ошибок не найдено, обновляем запись в таблице форумных постов с новыми данными из массива $rmsg.
    // Здесь мы обновляем пост в базе данных, используя данные из массива $rmsg, которые содержат измененную информацию о посте.
    Cot::$db->update(Cot::$db->forum_posts, $rmsg, "fp_id=$p");

    // Проверяем, если заголовок темы не пустой и данный пост является первым в теме.
    // Сравниваем ID первого поста в теме с текущим постом для обновления данных темы.
    if (
        !empty($rtopic['ft_title'])  // Проверяем, что заголовок темы не пустой.
        && Cot::$db->query("SELECT fp_id FROM " . Cot::$db->forum_posts . " WHERE fp_topicid = $q ORDER BY fp_id ASC LIMIT 1")
            ->fetchColumn() == $p  // Сравниваем ID первого поста в теме с ID текущего поста.
    ) {
        // Если заголовок темы начинается с символа "#", то удаляем его.
        // Это нужно для того, чтобы удалить лишний символ в случае его присутствия в заголовке темы.
        if (mb_substr($rtopic['ft_title'], 0, 1) == "#") {
            $rtopic['ft_title'] = str_replace('#', '', $rtopic['ft_title']);
        }

        // Формируем превью для темы, если текст сообщения не пустой, обрезая его до 120 символов.
        // Если текст сообщения существует, мы создаем превью для темы из первых 120 символов текста поста.
        $rtopic['ft_preview'] = !empty($rmsg['fp_text']) ? cot_string_truncate($rmsg['fp_text'], 120) : '';

        // Если превью темы слишком длинное, удаляем теги HTML и снова обрезаем до 120 символов.
        // Мы убираем HTML-теги, чтобы текст превью был чистым и без разметки.
        if (mb_strlen($rtopic['ft_preview']) > 128) {
            $rtopic['ft_preview'] = cot_string_truncate(strip_tags($rmsg['fp_text']), 120, false);
        }

        // Обновляем информацию о теме в базе данных.
        // Теперь мы обновляем саму тему в базе данных с новым превью и заголовком.
        Cot::$db->update(Cot::$db->forum_topics, $rtopic, "ft_id = $q");
    }

    // Выполняем перемещение файлов, если это необходимо (например, для прикрепленных файлов).
    // В случае, если файлы были загружены и нужно их переместить в соответствующие директории.
    cot_extrafield_movefiles();
}

// Вызов хуков, которые могут быть настроены для действия после обновления поста.
foreach (cot_getextplugins('forums.editpost.update.done') as $pl) {
    // Для каждого плагина, подключаем его и выполняем дополнительные действия.
    include $pl;
}

// Если включен кэш, очищаем кэш для форума и главной страницы (если это настроено).
if (Cot::$cache) {
    // Очищаем кэш форума, если в конфигурации включено кэширование для форума.
    if (Cot::$cfg['cache_forums']) {
        Cot::$cache->static->clearByUri(cot_url('forums'));  // Очищаем кэш форума по его URI.
    }

    // Очищаем кэш главной страницы, если включено кэширование для главной страницы.
    if (Cot::$cfg['cache_index']) {
        Cot::$cache->static->clear('index');  // Очищаем кэш главной страницы.
    }
}

// Перенаправляем пользователя на страницу форума с обновленной темой.
// После успешного обновления поста, пользователь перенаправляется обратно на страницу форума с этой темой.
cot_redirect(
    cot_url('forums', ['m' => 'posts', 'q' => $q , 'd' => $durl], '#' . $p, true)  // Формируем URL для перенаправления с текущими параметрами.
);

объяснение :

  1. Проверка ошибок:
    if (!cot_error_found()) {
    Эта строка проверяет, были ли ошибки при обработке формы. Если ошибок не было (функция cot_error_found() возвращает false), код продолжает выполнение, иначе — ошибок не найдено, и выполнение кода продолжается.

  2. Обновление поста:
    Cot::$db->update(Cot::$db->forum_posts, $rmsg, "fp_id=$p");
    Если ошибок нет, обновляется запись в таблице постов форума. Массив $rmsg содержит новые данные поста, а условие "fp_id=$p" указывает, какой именно пост должен быть обновлен по ID.

  3. Проверка первого поста в теме:
    Этот блок проверяет, является ли редактируемый пост первым в теме (то есть заголовком темы). Если это так, то обновляется информация о теме.

  4. Удаление символа "#" в заголовке:
    Если заголовок темы начинается с символа #, этот символ удаляется.

  5. Создание превью для темы:
    Создается превью темы, которое обрезается до 120 символов. Если текст слишком длинный, применяется метод для удаления HTML-тегов и повторного обрезания.

  6. Обновление темы:
    Если первый пост был отредактирован, то обновляется информация о самой теме в базе данных.

  7. Перемещение файлов:
    Если в процессе редактирования были прикреплены файлы, то с помощью функции cot_extrafield_movefiles() эти файлы перемещаются в нужную директорию.

  8. Вызов хуков:
    Код вызывает хуки forums.editpost.update.done, чтобы внешние плагины могли выполнить свои действия после обновления поста.

  9. Очищение кэша:
    Если включено кэширование, очищаются соответствующие кэши форума и главной страницы, чтобы отображались актуальные данные.

  10. Перенаправление пользователя:
    В конце пользователь перенаправляется на страницу форума с обновленной темой или постом, чтобы увидеть изменения.

 

// Подключаем файл, содержащий функции для работы с формами.
require_once cot_incfile('forms');

// Строим хлебные крошки для форума, начиная с пути к категории форума.
$crumbs = cot_forums_buildpath($s);

// Добавляем хлебную крошку для текущей темы форума с ее заголовком, с условием добавления символа "#", если тема в приватном режиме.
$crumbs[] = [
    cot_url('forums', "m=posts&p=" . $p, "#" . $p),
    (($rowt['ft_mode'] == 1) ? '# ' : '') . $rowt['ft_title']
];

// Добавляем хлебную крошку для редактирования поста с указанием маршрута и параметров.
$crumbs[] = [
    cot_url('forums', ['m' => 'editpost', 's' => $s, 'q' => $q, 'p' => $p, 'x' => Cot::$sys['xk']]),
    Cot::$L['Edit']
];

// Формируем заголовок страницы с использованием хлебных крошек.
$toptitle = cot_breadcrumbs($crumbs, Cot::$cfg['homebreadcrumb']);

// Если пользователь администратор, добавляем соответствующий маркер в заголовок.
$toptitle .= Cot::$usr['isadmin'] ? Cot::$R['forums_code_admin_mark'] : '';

// Устанавливаем подзаголовок страницы в соответствии с темой форума.
$sys['sublocation'] = Cot::$structure['forums'][$s]['title'];

// Устанавливаем параметры заголовка страницы для вывода информации о форуме, разделе и теме.
$title_params = array(
	'FORUM' => Cot::$L['Forums'],
	'SECTION' => Cot::$structure['forums'][$s]['title'],
	'TOPIC' => $rowt['ft_title'],
	'EDIT' => Cot::$L['Edit']
);

// Формируем заголовок страницы с учетом параметров.
Cot::$out['subtitle'] = cot_title('{EDIT} - {TOPIC}', $title_params);

// Инициализируем переменную для заголовка страницы, если она еще не была установлена.
if (!isset(Cot::$out['head'])) {
    Cot::$out['head'] = '';
}

// Добавляем мета-тег для индексации страницы, указывая, что эта страница не должна индексироваться.
Cot::$out['head'] .= Cot::$R['code_noindex'];

// Выполняем хуки, которые могут быть настроены для основной страницы редактирования поста.
foreach (cot_getextplugins('forums.editpost.main') as $pl)
{
    include $pl;
}

// Подключаем шаблон заголовка страницы.
require_once Cot::$cfg['system_dir'] . '/header.php';

// Задаем шаблон для страницы редактирования поста, выбирая соответствующий шаблон в зависимости от структуры форума.
$mskin = cot_tplfile(array('forums', 'editpost', Cot::$structure['forums'][$s]['tpl']));

// Создаем объект XTemplate для рендеринга шаблона.
$t = new XTemplate($mskin);

// Отображаем сообщения об ошибках или уведомлениях, если они есть.
cot_display_messages($t);

 

// Проверяем, является ли текущий пост первым в теме по его ID.
if (Cot::$db->query("SELECT fp_id FROM $db_forum_posts WHERE fp_topicid = $q ORDER BY fp_id ASC LIMIT 1")->fetchColumn() == $p) {
    // Если это первый пост в теме, задаем значения для полей формы редактирования темы.
    $t->assign([
        // Устанавливаем поле для редактирования заголовка темы с максимальной длиной 255 символов.
        'FORUMS_EDITPOST_FORM_TOPIC_TITTLE' => cot_inputbox(
            'text',
            'rtopictitle', // Имя поля формы для заголовка темы
            $rowt['ft_title'], // Текущее значение заголовка темы
            ['maxlength' => 255] // Устанавливаем максимальную длину для поля
        ),
        // Устанавливаем поле для редактирования описания темы с максимальной длиной 255 символов.
        'FORUMS_EDITPOST_FORM_TOPIC_DESCRIPTION' => cot_inputbox(
            'text',
            'rtopicdesc', // Имя поля формы для описания темы
            $rowt['ft_desc'], // Текущее значение описания темы
            ['maxlength' => 255] // Устанавливаем максимальную длину для поля
        ),
    ]);

 

// Проверяем, включен ли режим устаревшей версии (legacyMode) в конфигурации сайта.
if (isset(Cot::$cfg['legacyMode']) && Cot::$cfg['legacyMode']) {
    // Если режим устаревшей версии включен, выводим поля формы для редактирования темы.
    // Эти поля являются устаревшими и использовались до версии 0.9.26.
    // Присваиваем значение поля для заголовка темы с максимальной длиной 255 символов.
    $t->assign([
        'FORUMS_EDITPOST_TOPICTITTLE' => cot_inputbox('text', 'rtopictitle', $rowt['ft_title'], array('maxlength' => 255)),
        // Присваиваем значение поля для описания темы с максимальной длиной 255 символов.
        'FORUMS_EDITPOST_TOPICDESCRIPTION' => cot_inputbox('text', 'rtopicdesc', $rowt['ft_desc'], array('maxlength' => 255)),
    ]);
}

 

// Проверяем, есть ли дополнительные поля для тем форума в конфигурации.
if (!empty(Cot::$extrafields[Cot::$db->forum_topics])) {
    // Если дополнительные поля существуют, начинаем их обработку.
    foreach (Cot::$extrafields[Cot::$db->forum_topics] as $exfld) {
        // Преобразуем название поля в верхний регистр для использования в шаблоне.
        $uname = strtoupper($exfld['field_name']);
        
        // Строим значение для дополнительного поля, используя функцию для создания поля.
        // Значение поля будет отображаться в шаблоне как результат работы функции cot_build_extrafields.
        $exfld_val = cot_build_extrafields('rtopic' . $exfld['field_name'], $exfld, $rowt['ft_' . $exfld['field_name']]);
        
        // Получаем заголовок для дополнительного поля с помощью функции cot_extrafield_title.
        $exfld_title = cot_extrafield_title($exfld, 'forums_topic_');

        // Присваиваем значения в шаблон.
        // Здесь мы связываем значения дополнительного поля с конкретными переменными в шаблоне.
        $t->assign([
            'FORUMS_EDITPOST_FORM_TOPIC_' . $uname => $exfld_val, // Значение дополнительного поля для темы.
            'FORUMS_EDITPOST_FORM_TOPIC_' . $uname . '_TITLE' => $exfld_title, // Заголовок дополнительного поля.
            'FORUMS_EDITPOST_FORM_TOPIC_EXTRAFLD' => $exfld_val, // Общая переменная для дополнительного поля.
            'FORUMS_EDITPOST_FORM_TOPIC_EXTRAFLD_TITLE' => $exfld_title, // Общая переменная для заголовка поля.
        ]);

        // Проверяем, включен ли режим старой версии (legacyMode) в конфигурации.
        if (isset(Cot::$cfg['legacyMode']) && Cot::$cfg['legacyMode']) {
            // Если включен legacyMode, присваиваем старые значения для совместимости.
            $t->assign([
                'FORUMS_EDITPOST_TOPIC_' . $uname => $exfld_val, // Для старых версий системы.
                'FORUMS_EDITPOST_TOPIC_' . $uname . '_TITLE' => $exfld_title, // Для старых версий системы.
                'FORUMS_EDITPOST_TOPIC_EXTRAFLD' => $exfld_val, // Для старых версий системы.
                'FORUMS_EDITPOST_TOPIC_EXTRAFLD_TITLE' => $exfld_title, // Для старых версий системы.
            ]);
        }

        // Парсим шаблон для отображения дополнительных полей темы.
        // Это выполняется для каждого дополнительного поля, чтобы оно отобразилось в шаблоне.
        $t->parse('MAIN.FORUMS_EDITPOST_FIRSTPOST.TOPIC_EXTRAFLD');
    }
}

// Парсим основной шаблон для первого поста редактируемой темы.
// Это необходимо, чтобы обработать весь шаблон для первого поста темы.
$t->parse('MAIN.FORUMS_EDITPOST_FIRSTPOST');

 

// Присваиваем в шаблон название страницы редактирования поста форума.
$t->assign([
    'FORUMS_EDITPOST_TITLE' => Cot::$L['forums_editPost'], // Заголовок страницы редактирования поста.

    // Присваиваем в шаблон хлебные крошки, которые отображают путь навигации.
    'FORUMS_EDITPOST_BREADCRUMBS' => $toptitle, // Хлебные крошки для текущей страницы.

    // Присваиваем в шаблон строку, которая отображает, кто написал пост и когда он был обновлен.
    'FORUMS_EDITPOST_SUBTITLE' => Cot::$L['forums_postedby'] . ": <a href=\"users.php?m=details&id=" . $rowpost['fp_posterid'] . "\">" . $rowpost['fp_postername'] . "</a> @ " . cot_date('datetime_medium', $rowpost['fp_updated']),
    // Отображение времени последнего обновления поста в формате даты и времени.
    'FORUMS_EDITPOST_UPDATED' => cot_date('datetime_medium', $rowpost['fp_updated']), // Время обновления поста.

    // Отображение метки времени последнего обновления поста в виде метки времени.
    'FORUMS_EDITPOST_UPDATED_STAMP' => $rowpost['fp_updated'], // Метка времени последнего обновления.

    // Формируем URL для действия обновления поста в форме редактирования.
    'FORUMS_EDITPOST_FORM_ACTION' => cot_url('forums', "m=editpost&a=update&s=" . $s . "&q=" . $q . "&p=" . $p . '&d=' . $durl . "&" . cot_xg()), // URL для обновления поста.

    // Присваиваем в шаблон текстовую область для редактирования текста поста.
    'FORUMS_EDITPOST_FORM_TEXT' => cot_textarea('rmsgtext', $rowpost['fp_text'], 20, 56, '', 'input_textarea_'.$minimaxieditor), // Текстовая область для ввода текста поста.

    // Если время редактирования поста ограничено, то отображаем оставшееся время для редактирования.
    'FORUMS_EDITPOST_EDIT_TIMEOUT' => Cot::$cfg['forums']['edittimeout'] > 0
        ? cot_build_timegap(0, Cot::$cfg['forums']['edittimeout'] * 3600) // Оставшееся время редактирования.
        : '', // Если время редактирования не ограничено, оставляем пустое значение.
]);

 

// Проверяем, активирован ли режим совместимости (legacyMode).
if (isset(Cot::$cfg['legacyMode']) && Cot::$cfg['legacyMode']) {
    // Если активирован режим совместимости, выводим следующие данные, которые устарели с версии 0.9.26.
    
    // Присваиваем в шаблон заголовок страницы редактирования поста.
    $t->assign([
        'FORUMS_EDITPOST_PAGETITLE' => $toptitle, // Заголовок страницы редактирования поста.

        // Присваиваем в шаблон URL для отправки формы обновления поста.
        'FORUMS_EDITPOST_SEND' => cot_url('forums', "m=editpost&a=update&s=" . $s . "&q=" . $q . "&p=" . $p . '&d=' . $durl . "&" . cot_xg()), // URL для отправки формы обновления поста.

        // Присваиваем в шаблон текстовую область для редактирования текста поста.
        'FORUMS_EDITPOST_TEXT' => cot_textarea('rmsgtext', $rowpost['fp_text'], 20, 56, '', 'input_textarea_'.$minimaxieditor), // Текстовая область для ввода текста поста.

        // Если есть ограничение по времени редактирования, то показываем оставшееся время для редактирования.
        'FORUMS_EDITPOST_EDITTIMEOUT' => Cot::$cfg['forums']['edittimeout'] > 0
            ? cot_build_timegap(0, Cot::$cfg['forums']['edittimeout'] * 3600) // Оставшееся время для редактирования.
            : '', // Если времени на редактирование нет, оставляем пустое значение.
    ]);
}

 

// Проверяем, есть ли дополнительные поля (extra fields) для постов форума.
if (!empty(Cot::$extrafields[Cot::$db->forum_posts])) {
    // Если дополнительные поля существуют, перебираем их.
    foreach (Cot::$extrafields[Cot::$db->forum_posts] as $exfld) {
        // Преобразуем название поля в верхний регистр для использования в шаблоне.
        $uname = strtoupper($exfld['field_name']);

        // Генерируем HTML-код для дополнительных полей и их значений.
        $exfld_val = cot_build_extrafields('rmsg' . $exfld['field_name'], $exfld, $rowpost['fp_' . $exfld['field_name']]);
        
        // Получаем название для дополнительного поля.
        $exfld_title = cot_extrafield_title($exfld, 'forums_post_');

        // Присваиваем в шаблон значения для дополнительного поля.
        $t->assign([
            'FORUMS_EDITPOST_FORM_' . $uname => $exfld_val, // Значение дополнительного поля.
            'FORUMS_EDITPOST_FORM_' . $uname . '_TITLE' => $exfld_title, // Заголовок дополнительного поля.
            'FORUMS_EDITPOST_FORM_EXTRAFLD' => $exfld_val, // Значение дополнительного поля.
            'FORUMS_EDITPOST_FORM_EXTRAFLD_TITLE' => $exfld_title, // Заголовок дополнительного поля.
        ]);

        // Если активирован режим совместимости (legacyMode), выводим дополнительные значения для устаревших версий.
        if (isset(Cot::$cfg['legacyMode']) && Cot::$cfg['legacyMode']) {
            // Если активирован режим совместимости, выводим следующие данные, которые устарели с версии 0.9.26.
            $t->assign([
                'FORUMS_EDITPOST_' . $uname => $exfld_val, // Значение дополнительного поля.
                'FORUMS_EDITPOST_' . $uname . '_TITLE' => $exfld_title, // Заголовок дополнительного поля.
                'FORUMS_EDITPOST_EXTRAFLD' => $exfld_val, // Значение дополнительного поля.
                'FORUMS_EDITPOST_EXTRAFLD_TITLE' => $exfld_title, // Заголовок дополнительного поля.
            ]);
        }
        
        // Парсим шаблон для отображения дополнительного поля.
        $t->parse('MAIN.EXTRAFLD');
    }
}

 

/* === Hook === */
// Запускаем все расширения (плагины), подключенные для хука 'forums.editpost.tags'.
// Этот код позволяет добавить дополнительные действия или изменения перед выводом содержимого страницы редактирования поста.
foreach (cot_getextplugins('forums.editpost.tags') as $pl) {
    include $pl; // Подключаем каждый плагин из списка расширений.
}
/* ===== */

// Парсим основной шаблон, который будет использован для вывода страницы редактирования поста.
$t->parse('MAIN');

// Отображаем результат парсинга шаблона на экран.
$t->out('MAIN');

// Подключаем файл footer.php для завершения загрузки страницы и отображения футера.
require_once Cot::$cfg['system_dir'] . '/footer.php'; 

 

 

 

 

19 минут чтения Sodium Carbonate

Комментарии (0)

Комментарии отсутствуют
Добавление комментариев доступно только зарегистрированным пользователям

Автор контента

webitproff

Оффлайн

Sodium Carbonate

Последняя авторизация: 19.07.2026 01:13

  • Страница размещена: 10.02.2025 17:07
  • Последнее обновление: 11.02.2025 19:57

Похожие страницы

Файл forums.setup.php в Cotonti
1 Описание файла forums.setup.php в Cotonti CMF 1. Основное назначение файла и его место в системе Cotonti Файл
Файл forums.php в Cotonti
2 Файл forums.php является основным скриптом, отвечающим за работу модуля форума в системе Cotonti CMF. Он расположен в
Файл "forums.extrafields.php" в системе Cotonti CMF
3 Файл "forums.extrafields.php" в системе Cotonti CMF является частью модуля Forums и используется для
Файл "forums.admin.php" в Cotonti
4 Файл "forums.admin.php" в Cotonti CMF — это административный скрипт, который управляет функциональностью
Файл forums.trashcan.php в Cotonti
5 Файл forums.trashcan.php в Cotonti CMF предназначен для обработки и поддержки функционала корзины для модуля форумов.