Сторінки, статті та новини
Інструменти та плагіни
Заготовка заголовок


Опис як приклад заготовки. Приклад текстового контенту для подальшої кастомізації шаблону "Index36".

Редагувати шаблон можна на власний розсуд. Якщо у вас немає часу або знань – завжди можна замовити адаптацію шаблону, написавши мені через GitHub або особисті повідомлення на публічній сторінці маркетплейсу цифрових товарів.

Файл 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. В случае, если хотя бы один пост остался, пользователя перенаправляют на страницу с постами темы.

 

 
Коментарі відсутні
Додавання коментарів доступне лише зареєстрованим користувачам
Обліковий запис