Pages, Articles & News
Tools & Plugins
Example / Placeholder Title


Description as an example placeholder. Sample text content for further customization of the "Index36" template.

You are free to edit and customize the template however you like. If you don’t have time or enough knowledge — you can always order template adaptation by contacting me via GitHub or private messages on the digital goods marketplace.

Файл forums.posts.php в Cotonti. Часть 2

Начинаем изучать код файла "forums.posts.php" в Cotonti CMF, который находится в дириктории: /modules/forums/inc/ php-фреймворка.

Файл forums.posts.php в Cotonti. Часть 2

 

if ($a == 'newpost' && !empty($s) && !empty($q))  // Проверяем, что действие $a равно 'newpost' (новый пост), а также что заданы переменные $s (раздел форума) и $q (ID темы).
{
	cot_shield_protect();  // Защита от спама и флудеров с помощью встроенного механизма Cotonti.

	Cot::$db->query("SELECT ft_state FROM $db_forum_topics WHERE ft_id = $q")->fetchColumn() && cot_die();  
	// Выполняем SQL-запрос к базе данных, чтобы получить состояние (ft_state) темы с ID $q. 
	// Если запрос вернул ненулевое значение (тема закрыта или удалена), вызываем `cot_die()`, завершив выполнение скрипта.

	$sql_forums = Cot::$db->query("SELECT fp_id, fp_text, fp_posterid, fp_creation, fp_updated, fp_updater FROM $db_forum_posts
		WHERE fp_topicid = $q ORDER BY fp_creation DESC LIMIT 1");  
	// Запрашиваем последний пост в теме $q, сортируя их по дате создания (fp_creation) в порядке убывания (DESC), 
	// чтобы получить самый новый пост (LIMIT 1).

	if ($row = $sql_forums->fetch()) {  // Если удалось получить данные последнего поста:
		if (
            Cot::$cfg['forums']['antibumpforums']  // Проверяем, включена ли функция защиты от "бампинга" (искусственного поднятия темы).
            && (
                (Cot::$usr['id'] == 0 && $row['fp_posterid'] == 0 && $row['fp_posterip'] == Cot::$usr['ip'])  
                // Если текущий пользователь не авторизован (гость), а IP последнего поста совпадает с его IP, запрещаем отправку нового поста.
                || ($row['fp_posterid'] > 0 && $row['fp_posterid'] == Cot::$usr['id'])  
                // Если последний пост принадлежит текущему пользователю (авторизованному), запрещаем отправку нового поста.
            )
        ) {
			cot_die();  // Завершаем выполнение, если обнаружена попытка "бампинга".
		}

		$merge = (!Cot::$cfg['forums']['antibumpforums'] && Cot::$cfg['forums']['mergeforumposts'] && $row['fp_posterid'] == Cot::$usr['id']) ? true : false;  
		// Проверяем, можно ли объединить новый пост с последним постом. 
		// Это возможно, если:
		// - Отключена защита от бампинга (`antibumpforums = false`).
		// - Включена настройка объединения сообщений (`mergeforumposts = true`).
		// - Последний пост написан текущим пользователем.

		$merge = ($merge && Cot::$cfg['forums']['mergetimeout'] > 0 && (($sys['now'] - $row['fp_updated']) > (Cot::$cfg['forums']['mergetimeout'] * 3600))) ? false : $merge;
		// Если объединение сообщений разрешено (`$merge = true`), проверяем, не истек ли лимит времени для объединения (`mergetimeout`).
		// Если время между обновлением последнего поста (`fp_updated`) и текущим моментом (`sys['now']`) больше лимита (`mergetimeout` в часах),
		// то объединение отменяется (`$merge = false`).

	} else {
		cot_die();  // Если в теме еще нет постов (запрос `$sql_forums` не вернул строк), выполнение скрипта завершается.
	}

Объяснение логики:

  1. Проверка входных данных

    • Убедимся, что действие $a — это newpost (новый пост).
    • Проверяем, что заданы идентификаторы $s (раздел форума) и $q (ID темы).
  2. Защита от спама

    • Функция cot_shield_protect() предотвращает флуд и возможные атаки.
  3. Проверка состояния темы

    • Выполняется SQL-запрос, чтобы проверить состояние темы (ft_state).
    • Если тема закрыта (ft_state не пустое), то выполнение прекращается.
  4. Получение последнего поста в теме

    • Запрос выбирает последний пост в теме (сортировка ORDER BY fp_creation DESC).
  5. Проверка на "бампинг"

    • Если активирована настройка antibumpforums, проверяется, чтобы пользователь не "поднимал" тему.
    • Если последний пост сделан этим же пользователем, то новый пост запрещается.
  6. Объединение постов

    • Если активирована настройка mergeforumposts, новый пост объединяется с последним, если его автор тот же.
    • Однако, если прошло больше времени, чем указано в mergetimeout, объединение отменяется.
  7. Если тема пуста — выход

    • Если в теме еще нет сообщений, выполнение скрипта завершается (cot_die()).

 

$rmsg = array();  
// Инициализация массива $rmsg для хранения данных нового поста.

$rmsg['fp_text'] = cot_import('rmsgtext', 'P', 'HTM');  
// Импорт текста нового сообщения (из POST-параметра 'rmsgtext'), который будет сохранен как HTML.

$rmsg['fp_updated'] = (int)$sys['now'];  
// Устанавливаем время обновления поста (текущее время из системы).

$rmsg['fp_posterip'] = Cot::$usr['ip'];  
// Сохраняем IP-адрес пользователя, который создает новый пост.

if (mb_strlen($rmsg['fp_text']) < Cot::$cfg['forums']['minpostlength']) {  
// Проверяем, что длина текста сообщения больше минимальной длины, заданной в конфигурации форума.
	cot_error('forums_messagetooshort', 'rmsgtext');  
	// Если длина текста слишком короткая, вызываем ошибку с сообщением 'forums_messagetooshort' для поля 'rmsgtext'.
	cot_redirect(cot_url('forums', "m=posts&q=$q&n=last", '#bottom', true));  
	// Перенаправляем пользователя обратно на страницу форума, на последний пост (с добавлением якоря '#bottom' для прокрутки).
}

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

foreach (cot_getextplugins('forums.posts.newpost.first') as $pl) {  
// Выполняем хуки, если они есть, для действия 'forums.posts.newpost.first' (перед созданием нового поста).
	include $pl;  
	// Подключаем каждый плагин, который расширяет функционал на этом этапе.
}

Объяснение логики:

  1. Инициализация массива

    • Создается массив $rmsg, который будет хранить данные нового поста.
  2. Импорт текста поста

    • Текст сообщения (rmsgtext) импортируется с помощью функции cot_import(). В данном случае, текст обрабатывается как HTML.
  3. Проверка минимальной длины сообщения

    • Если длина текста сообщения меньше минимально установленной длины (minpostlength), пользователю выводится ошибка, и он перенаправляется обратно на форум.
  4. Обработка дополнительных полей

    • Если в таблице постов форума определены дополнительные поля (например, кастомные поля), они импортируются и добавляются в массив $rmsg.
  5. Выполнение хуков

    • Если существуют плагины, подключенные к хуку forums.posts.newpost.first, они выполняются. Это позволяет расширить функциональность при создании нового поста, например, добавлением дополнительной обработки перед сохранением поста.

 

if (!cot_error_found()) {  
// Проверяем, если нет ошибок, которые были добавлены ранее с помощью cot_error().
	if (!$merge) {  
		// Если пост не нужно сливать с предыдущим (нет режима слияния сообщений).
		$rmsg['fp_topicid'] = (int) $q;  
		// Устанавливаем ID темы (используем значение переменной $q, которое хранит ID темы).

		$rmsg['fp_cat'] = $s;  
		// Устанавливаем категорию форума (с помощью переменной $s).

		$rmsg['fp_posterid'] = (int) Cot::$usr['id'];  
		// Устанавливаем ID пользователя, который создает пост (из информации о пользователе Cot::$usr).

		$rmsg['fp_postername'] = Cot::$usr['name'];  
		// Устанавливаем имя пользователя, который создает пост.

		$rmsg['fp_creation'] = (int) $sys['now'];  
		// Устанавливаем дату создания поста (текущее время системы).

		$rmsg['fp_updater'] = 0;  
		// Устанавливаем поле обновления в 0, так как это новый пост.

		Cot::$db->insert($db_forum_posts, $rmsg);  
		// Вставляем новый пост в таблицу форумов ($db_forum_posts).

		$p = Cot::$db->lastInsertId();  
		// Получаем ID последнего вставленного поста.

        cot_forums_resyncTopic($q, Cot::$usr['id']);  
        // Пересчитываем статистику темы (например, обновляем время последнего поста, количество сообщений и т. д.).

        cot_forums_updateStructureCounters($s);  
        // Обновляем счетчики категорий форума для текущей категории.

	} else {  
		// Если пост нужно слить с предыдущим (режим слияния сообщений).
		$p = (int) $row['fp_id'];  
		// Получаем ID поста, который будет слит (из строки $row).

		$gap_base = empty($row['fp_updated']) ? $row['fp_creation'] : $row['fp_updated'];  
		// Если у предыдущего поста нет времени обновления, используем время его создания. Иначе, используем время последнего обновления.

		$updated = sprintf(Cot::$L['forums_mergetime'], cot_build_timegap($gap_base, Cot::$sys['now']));  
		// Создаем строку, которая показывает разницу во времени между предыдущим и текущим сообщением.

		$rmsg['fp_text'] = $row['fp_text'] . cot_rc('forums_code_update', array('updated' => $updated)) . $rmsg['fp_text'];  
		// Добавляем в текст нового сообщения информацию о времени обновления, а затем добавляем сам текст нового поста.

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

		Cot::$db->update($db_forum_posts, $rmsg, 'fp_id=' . $row['fp_id']);  
		// Обновляем пост в таблице форумов ($db_forum_posts) с новыми данными из массива $rmsg.

		Cot::$db->update($db_forum_topics, array('ft_updated' => $sys['now']), "ft_id = $q");  
		// Обновляем время последнего поста в теме (таблица $db_forum_topics).

        cot_forums_resyncTopic($q, false);  
        // Пересчитываем статистику темы без изменения ID пользователя.

        cot_forums_updateStructureCounters($s);  
        // Обновляем счетчики категории форума.
	}
}

Объяснение логики:

  1. Проверка наличия ошибок

    • Код выполняется, если нет ошибок, с помощью проверки !cot_error_found(). Это позволяет убедиться, что до выполнения не произошло ошибок, связанных с данными, переданными в форму.
  2. Создание нового поста (если не используется слияние)

    • Если не нужно сливать пост с предыдущим (переменная $merge равна false), то:
      • Вставляется новый пост с данными о теме, категории, авторе, времени создания.
      • Также выполняется пересинхронизация статистики темы и обновление счетчиков категории.
  3. Слияние постов (если используется слияние)

    • Если активирован режим слияния сообщений (переменная $merge равна true), то:
      • Получаем ID поста, с которым нужно выполнить слияние.
      • Вычисляется разница во времени между текущим и предыдущим сообщением.
      • В текст нового сообщения добавляется информация о времени обновления.
      • Обновляется информация о посте в базе данных, и тема обновляется с новым временем последнего поста.
  4. Пересинхронизация и обновление статистики

    • После добавления или обновления поста, выполняются два важных действия:
      • Пересинхронизация статистики темы (cot_forums_resyncTopic).
      • Обновление счетчиков категории форума (cot_forums_updateStructureCounters).

 

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

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

 /* ===== */

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

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

cot_shield_update(30, "New post");  
// Обновление защиты от повторных отправок формы (например, защиты от спама). Параметры определяют период (30 секунд) и сообщение.

cot_redirect(  
    cot_url('forums', ['m' => 'posts', 'q' => $q, 'n' => 'last'], '#bottom', true)  
);  
// Перенаправление на страницу форума, где отображается последний пост в теме. URL включает параметры: ID темы ($q) и переход к последнему сообщению ('n' => 'last').
// #bottom указывает браузеру прокрутить страницу вниз к последнему сообщению.

Объяснение:

  1. Перемещение файлов с дополнительными полями

    • cot_extrafield_movefiles() выполняет перемещение файлов, которые могут быть прикреплены к сообщениям через дополнительные поля. Это необходимо, чтобы управлять прикрепленными файлами, например, изображениями, которые были загружены в пост.
  2. Запуск плагинов после создания нового поста

    • Цикл foreach (cot_getextplugins('forums.posts.newpost.done') активирует все внешние плагины, подключенные к событию завершения создания поста. Эти плагины могут выполнять дополнительные действия, такие как уведомления, аналитика, интеграции с внешними сервисами и т.д.
  3. Очистка кэша

    • Если включено кэширование:
      • Очистка кэша форума: если обновилась тема или пост, выполняется удаление старого кэша для форума с помощью Cot::$cache->static->clearByUri(cot_url('forums')).
      • Очистка кэша главной страницы сайта, если она также кэшируется, с помощью Cot::$cache->static->clear('index').
  4. Обновление защиты от повторных отправок

    • Вызов cot_shield_update(30, "New post") обновляет защиту от повторных отправок, устанавливая 30-секундный период защиты, чтобы предотвратить повторную отправку формы при создании поста.
  5. Перенаправление после успешного создания поста

    • После завершения всех операций, связанных с созданием поста, выполняется редирект на страницу с последним постом в теме. Это позволяет пользователю сразу же увидеть добавленный пост в конце обсуждения.
} elseif (  
    $a == 'delete'  // Проверяется, что действие равно "delete" (удалить).
    && Cot::$usr['id'] > 0  // Пользователь должен быть авторизован (его ID больше 0).
    && !empty($s)  // Проверяется, что передан код категории форума (раздел).
    && !empty($q)  // Проверяется, что передан ID темы форума.
    && !empty($p)  // Проверяется, что передан ID поста.
    && (  
        Cot::$usr['isadmin']  // Если пользователь является администратором, то ему разрешено удалить любой пост.
        || (  
            $fp_posterid == Cot::$usr['id']  // Если пользователь является автором поста, то ему разрешено удалять свои посты.
            && (  
                Cot::$cfg['forums']['edittimeout'] == '0'  // Если настройка времени редактирования отключена (0 часов), то пользователь может удалить пост в любое время.
                || Cot::$sys['now'] - $row['fp_creation'] < Cot::$cfg['forums']['edittimeout'] * 3600  // Если прошло меньше времени, чем указано в настройке форума для редактирования поста (например, 1 час).
            )  
        )  
    )  
) {  
    cot_check_xg();  // Функция для проверки на наличие действующего токена безопасности, предотвращающая атаки типа CSRF.

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

Пояснение:

  • Проверка условий:
    Условие внутри elseif выполняется только если действие ($a) равно "delete", и если все параметры (s, q, p) присутствуют и валидны. Также проверяется, что пользователь либо администратор, либо автор поста, который пытается удалить свой пост, и что время для редактирования не вышло, если оно ограничено в настройках форума.

  • cot_check_xg():
    Это стандартная защита от CSRF (Cross-Site Request Forgery) атак. Функция проверяет, что запрос был отправлен с правильным токеном, который подтверждает, что запрос действительно был инициирован пользователем, а не злоумышленником.

  • Хук для плагинов:
    С помощью функции cot_getextplugins и хука 'forums.posts.delete.first' можно подключить и выполнить дополнительные действия, которые разработчики или администраторы хотят выполнить перед удалением поста. Например, это может быть создание записи в логе, отправка уведомлений пользователю или другим пользователям, проверка на выполнение дополнительных условий и так далее.

 

$row = Cot::$db->query("SELECT * FROM $db_forum_posts WHERE fp_id = ? AND fp_topicid = ? AND fp_cat = ? LIMIT 1",  // Выполняется SQL-запрос для получения поста из базы данных, проверяя ID поста ($p), ID темы ($q) и код категории ($s).
    array($p, $q, $s))->fetch();  // Подставляем параметры запроса: ID поста, ID темы и код категории.
is_array($row) || cot_die();  // Проверяется, что результат запроса представляет собой массив (т.е. пост найден). Если нет, вызывает ошибку и завершает выполнение.

$first_id = Cot::$db->query("SELECT fp_id FROM $db_forum_posts WHERE fp_topicid = ? LIMIT 1", array($q))->fetchColumn();  // Выполняется SQL-запрос для получения ID первого поста в теме ($q).
if ($p == $first_id)  // Проверка, если текущий пост является первым постом в теме.
{
    if (Cot::$usr['isadmin'])  // Если пользователь является администратором.
    {
        // Если пост является первым в теме, перенаправляем на страницу подтверждения удаления темы.
        cot_redirect(str_replace('&amp;', '&', cot_confirm_url(cot_url('forums', 'm=topics&a=delete&s='.$s.'&q='.$q.'&x='.$sys['xk'], '', true), 'forums', 'forums_confirm_delete_topic')));
    }
    else
    {
        // Если пользователь не администратор, выводим ошибку (пользователи не могут удалять темы).
        cot_die();
    }
}

Пояснение:

  • Запрос поста:
    SQL-запрос извлекает данные поста из базы данных по его ID ($p), ID темы ($q) и категории ($s). После выполнения запроса, с помощью метода fetch(), извлекается одна строка данных из таблицы. Если результат не является массивом, программа завершится с ошибкой.

  • Проверка первого поста:
    Еще один SQL-запрос извлекает ID первого поста в теме. После этого происходит проверка: если текущий пост является первым в теме (т.е. его ID совпадает с ID первого поста), то выполняется дальнейшая логика.

  • Удаление темы:
    Если пользователь является администратором, его перенаправляют на страницу подтверждения удаления всей темы (с использованием cot_redirect). Для этого формируется URL, который включает параметры для удаления темы (с помощью функции cot_url и cot_confirm_url).

  • Проверка прав пользователя:
    Если пользователь не является администратором, программа вызывает ошибку с помощью cot_die(), и дальнейшая обработка запроса не происходит, т.к. обычные пользователи не имеют прав на удаление темы.

 

foreach($cot_extrafields[$db_forum_posts] as $exfld) {  // Цикл по всем дополнительным полям для таблицы постов форума.
    cot_extrafield_unlinkfiles($row['fp_'.$exfld['field_name']], $exfld);  // Для каждого дополнительного поля выполняется удаление связанных файлов, если они существуют. Используется функция `cot_extrafield_unlinkfiles`.
}

Cot::$db->delete($db_forum_posts, 'fp_id = ? AND fp_topicid = ? AND fp_cat = ?', array($p, $q, $s));  // Выполняется удаление поста из таблицы `db_forum_posts`, где ID поста ($p), ID темы ($q) и код категории ($s) совпадают.

cot_forums_resyncTopic($q, $fp_posterid);  // Пересинхронизация темы. Эта функция обновляет информацию о теме (например, количество постов) после удаления поста.

cot_log("Deleted post #" . $p, 'forums', 'delete post', 'done');  // Логирование действия удаления поста с ID $p. В журнал записывается сообщение о выполнении операции удаления.

foreach (cot_getextplugins('forums.posts.delete.done') as $pl) {  // Запуск внешних плагинов после завершения удаления поста.
    include $pl;  // Подключение плагинов, если они существуют.
}

Пояснение:

  • Удаление файлов, связанных с дополнительными полями:
    Для каждого дополнительного поля, связанного с постами в форуме, вызывается функция cot_extrafield_unlinkfiles, которая удаляет связанные файлы (например, прикрепленные файлы или изображения). Это позволяет избежать "мертвых" ссылок или файлов, оставшихся после удаления поста.

  • Удаление поста:
    В SQL-запросе происходит удаление записи из таблицы постов в базе данных, где значения полей ID поста, ID темы и код категории совпадают с переданными параметрами.

  • Пересинхронизация темы:
    После удаления поста вызывается функция cot_forums_resyncTopic, которая обновляет статистику темы (например, количество постов и другие параметры), чтобы отражать изменения.

  • Логирование:
    Операция удаления поста логируется с помощью функции cot_log. Это позволяет отслеживать удаление постов в административной панели и хранить запись об этом в журнале.

  • Запуск плагинов:
    Если существуют сторонние плагины, которые должны быть выполнены после удаления поста, они будут подключены с помощью цикла foreach и функции cot_getextplugins. Эти плагины могут выполнять дополнительные действия, такие как уведомления или обработка данных после удаления поста.

 

 

if (
    Cot::$db->query('SELECT COUNT(*) FROM ' . Cot::$db->forum_posts . ' WHERE fp_topicid = ?', $q)  // Выполняется запрос для подсчета количества постов в теме с ID $q.
    ->fetchColumn() == 0  // Если количество постов в теме равно 0 (то есть тема пуста).
) {
    // Если в теме нет постов, то удаляем саму тему.
    $sqlTopic = Cot::$db->query('SELECT * FROM ' . Cot::$db->forum_topics . ' WHERE ft_id = ?', $q);  // Выполняется запрос, чтобы получить информацию о теме с ID $q.
    if ($row = $sqlTopic->fetch()) {  // Если тема существует (нашлась в базе данных).
        cot_forums_prunetopics('single', $s, $q);  // Вызов функции для удаления темы. Тип удаления — "single" (одиночная тема), категория — $s, ID темы — $q.

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

        cot_log('Delete topic #' . $q . " (no post left)", 'forums', 'delete topic', 'done');  // Логирование события удаления темы без постов в журнал.
    }

    cot_forums_updateStructureCounters($s);  // Обновление счетчиков структуры форума (например, количество тем в категории $s).
    cot_redirect(cot_url('forums', ['m' => 'topics', 's' => $s], '', true));  // Перенаправление на список тем в категории после удаления темы.
} else {
    // Если в теме остались хотя бы 1 пост.
    cot_forums_updateStructureCounters($s);  // Обновление счетчиков структуры форума для категории $s.
    cot_redirect(
        cot_url(
            'forums',
            ['m' => 'posts', 'q' => $q, 'd' => $durl,],  // Перенаправление на страницу темы с постами.
            '#' . $row['fp_id'],  // Переход к первому посту в теме.
            true
        )
    );
}

Пояснение:

  1. Проверка наличия постов в теме:
    Выполняется запрос к базе данных для подсчета количества постов в теме с помощью SQL-запроса. Если количество постов равно нулю, это означает, что тема пуста.

  2. Удаление пустой темы:
    Если тема не содержит постов, то выполняется удаление темы с использованием функции cot_forums_prunetopics. Параметр 'single' указывает, что нужно удалить только одну тему. После этого выполняется запуск плагинов через cot_getextplugins, которые могут обрабатывать это событие (например, выполнить дополнительные действия или уведомления).

  3. Логирование события:
    Когда тема удалена, в журнал добавляется запись об этом событии с помощью cot_log, где указано, что тема была удалена из-за отсутствия постов.

  4. Обновление счетчиков:
    После удаления темы или при нахождении постов в теме, обновляются счетчики структуры форума через функцию cot_forums_updateStructureCounters. Это необходимо для актуализации статистики, например, количество постов и тем.

  5. Перенаправление пользователя:
    Если тема была удалена, пользователя перенаправляют на страницу списка тем категории через cot_redirect. В случае, если хотя бы один пост остался, пользователя перенаправляют на страницу с постами темы.

 

 
No comments yet
Only registered users can post new comments
Account