getId(); if($topicId < 1 && $postId > 0) { $postInfo = forum_post_find($postId, $topicUserId); if(!empty($postInfo['topic_id'])) { $topicId = (int)$postInfo['topic_id']; } } $topic = forum_topic_get($topicId, true); $perms = $topic ? forum_perms_get_user($topic['forum_id'], $topicUserId)[MSZ_FORUM_PERMS_GENERAL] : 0; if(isset($topicUser) && $topicUser->hasActiveWarning()) $perms &= ~MSZ_FORUM_PERM_SET_WRITE; $topicIsNuked = empty($topic['topic_id']); $topicIsDeleted = !empty($topic['topic_deleted']); $canDeleteAny = perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST); if($topicIsNuked || $topicIsDeleted) { $topicRedirectInfo = forum_topic_redir_info($topicId); Template::set('topic_redir_info', $topicRedirectInfo); if($topicIsNuked || !$canDeleteAny) { if(empty($topicRedirectInfo)) echo render_error(404); else header('Location: ' . $topicRedirectInfo->topic_redir_url); return; } } if(!perms_check($perms, MSZ_FORUM_PERM_VIEW_FORUM)) { echo render_error(403); return; } $topicIsLocked = !empty($topic['topic_locked']); $topicIsArchived = !empty($topic['topic_archived']); $topicPostsTotal = (int)($topic['topic_count_posts'] + $topic['topic_count_posts_deleted']); $topicIsFrozen = $topicIsArchived || $topicIsDeleted; $canDeleteOwn = !$topicIsFrozen && !$topicIsLocked && perms_check($perms, MSZ_FORUM_PERM_DELETE_POST); $canBumpTopic = !$topicIsFrozen && perms_check($perms, MSZ_FORUM_PERM_BUMP_TOPIC); $canLockTopic = !$topicIsFrozen && perms_check($perms, MSZ_FORUM_PERM_LOCK_TOPIC); $canNukeOrRestore = $canDeleteAny && $topicIsDeleted; $canDelete = !$topicIsDeleted && ( $canDeleteAny || ( $topicPostsTotal > 0 && $topicPostsTotal <= MSZ_FORUM_TOPIC_DELETE_POST_LIMIT && $canDeleteOwn && $topic['author_user_id'] === $topicUserId ) ); $validModerationModes = [ 'delete', 'restore', 'nuke', 'bump', 'lock', 'unlock', ]; if(in_array($moderationMode, $validModerationModes, true)) { if(!CSRF::validateRequest()) { echo render_info("Couldn't verify this request, please refresh the page and try again.", 403); return; } header(CSRF::header()); if(!UserSession::hasCurrent()) { echo render_info('You must be logged in to manage posts.', 401); return; } if($topicUser->isBanned()) { echo render_info('You have been banned, check your profile for more information.', 403); return; } if($topicUser->isSilenced()) { echo render_info('You have been silenced, check your profile for more information.', 403); return; } switch($moderationMode) { case 'delete': $canDeleteCode = forum_topic_can_delete($topic, $topicUserId); $canDeleteMsg = ''; $responseCode = 200; switch($canDeleteCode) { case MSZ_E_FORUM_TOPIC_DELETE_USER: $responseCode = 401; $canDeleteMsg = 'You must be logged in to delete topics.'; break; case MSZ_E_FORUM_TOPIC_DELETE_TOPIC: $responseCode = 404; $canDeleteMsg = "This topic doesn't exist."; break; case MSZ_E_FORUM_TOPIC_DELETE_DELETED: $responseCode = 404; $canDeleteMsg = 'This topic has already been marked as deleted.'; break; case MSZ_E_FORUM_TOPIC_DELETE_OWNER: $responseCode = 403; $canDeleteMsg = 'You can only delete your own topics.'; break; case MSZ_E_FORUM_TOPIC_DELETE_OLD: $responseCode = 401; $canDeleteMsg = 'This topic has existed for too long. Ask a moderator to remove if it absolutely necessary.'; break; case MSZ_E_FORUM_TOPIC_DELETE_PERM: $responseCode = 401; $canDeleteMsg = 'You are not allowed to delete topics.'; break; case MSZ_E_FORUM_TOPIC_DELETE_POSTS: $responseCode = 403; $canDeleteMsg = 'This topic already has replies, you may no longer delete it. Ask a moderator to remove if it absolutely necessary.'; break; case MSZ_E_FORUM_TOPIC_DELETE_OK: break; default: $responseCode = 500; $canDeleteMsg = sprintf('Unknown error \'%d\'', $canDelete); } if($canDeleteCode !== MSZ_E_FORUM_TOPIC_DELETE_OK) { echo render_info($canDeleteMsg, $responseCode); break; } if(!isset($_GET['confirm'])) { Template::render('forum.confirm', [ 'title' => 'Confirm topic deletion', 'class' => 'far fa-trash-alt', 'message' => sprintf('You are about to delete topic #%d. Are you sure about that?', $topic['topic_id']), 'params' => [ 't' => $topic['topic_id'], 'm' => 'delete', ], ]); break; } elseif(!$submissionConfirmed) { url_redirect( 'forum-topic', ['topic' => $topic['topic_id']] ); break; } $deleteTopic = forum_topic_delete($topic['topic_id']); if($deleteTopic) AuditLog::create(AuditLog::FORUM_TOPIC_DELETE, [$topic['topic_id']]); if(!$deleteTopic) { echo render_error(500); break; } url_redirect('forum-category', [ 'forum' => $topic['forum_id'], ]); break; case 'restore': if(!$canNukeOrRestore) { echo render_error(403); break; } if(!isset($_GET['confirm'])) { Template::render('forum.confirm', [ 'title' => 'Confirm topic restore', 'class' => 'fas fa-magic', 'message' => sprintf('You are about to restore topic #%d. Are you sure about that?', $topic['topic_id']), 'params' => [ 't' => $topic['topic_id'], 'm' => 'restore', ], ]); break; } elseif(!$submissionConfirmed) { url_redirect('forum-topic', [ 'topic' => $topic['topic_id'], ]); break; } $restoreTopic = forum_topic_restore($topic['topic_id']); if(!$restoreTopic) { echo render_error(500); break; } AuditLog::create(AuditLog::FORUM_TOPIC_RESTORE, [$topic['topic_id']]); url_redirect('forum-category', [ 'forum' => $topic['forum_id'], ]); break; case 'nuke': if(!$canNukeOrRestore) { echo render_error(403); break; } if(!isset($_GET['confirm'])) { Template::render('forum.confirm', [ 'title' => 'Confirm topic nuke', 'class' => 'fas fa-radiation', 'message' => sprintf('You are about to PERMANENTLY DELETE topic #%d. Are you sure about that?', $topic['topic_id']), 'params' => [ 't' => $topic['topic_id'], 'm' => 'nuke', ], ]); break; } elseif(!$submissionConfirmed) { url_redirect('forum-topic', [ 'topic' => $topic['topic_id'], ]); break; } $nukeTopic = forum_topic_nuke($topic['topic_id']); if(!$nukeTopic) { echo render_error(500); break; } AuditLog::create(AuditLog::FORUM_TOPIC_NUKE, [$topic['topic_id']]); url_redirect('forum-category', [ 'forum' => $topic['forum_id'], ]); break; case 'bump': if($canBumpTopic && forum_topic_bump($topic['topic_id'])) { AuditLog::create(AuditLog::FORUM_TOPIC_BUMP, [$topic['topic_id']]); } url_redirect('forum-topic', [ 'topic' => $topic['topic_id'], ]); break; case 'lock': if($canLockTopic && !$topicIsLocked && forum_topic_lock($topic['topic_id'])) { AuditLog::create(AuditLog::FORUM_TOPIC_LOCK, [$topic['topic_id']]); } url_redirect('forum-topic', [ 'topic' => $topic['topic_id'], ]); break; case 'unlock': if($canLockTopic && $topicIsLocked && forum_topic_unlock($topic['topic_id'])) { AuditLog::create(AuditLog::FORUM_TOPIC_UNLOCK, [$topic['topic_id']]); } url_redirect('forum-topic', [ 'topic' => $topic['topic_id'], ]); break; } return; } $topicPosts = $topic['topic_count_posts']; if($canDeleteAny) { $topicPosts += $topic['topic_count_posts_deleted']; } $topicPagination = new Pagination($topicPosts, MSZ_FORUM_POSTS_PER_PAGE, 'page'); if(isset($postInfo['preceeding_post_count'])) { $preceedingPosts = $postInfo['preceeding_post_count']; if($canDeleteAny) { $preceedingPosts += $postInfo['preceeding_post_deleted_count']; } $topicPagination->setPage(floor($preceedingPosts / $topicPagination->getRange()), true); } if(!$topicPagination->hasValidOffset()) { echo render_error(404); return; } Template::set('topic_perms', $perms); $posts = forum_post_listing( $topic['topic_id'], $topicPagination->getOffset(), $topicPagination->getRange(), perms_check($perms, MSZ_FORUM_PERM_DELETE_ANY_POST) ); if(!$posts) { echo render_error(404); return; } $canReply = !$topicIsArchived && !$topicIsLocked && !$topicIsDeleted && perms_check($perms, MSZ_FORUM_PERM_CREATE_POST); forum_topic_mark_read($topicUserId, $topic['topic_id'], $topic['forum_id']); Template::render('forum.topic', [ 'topic_breadcrumbs' => forum_get_breadcrumbs($topic['forum_id']), 'global_accent_colour' => forum_get_colour($topic['forum_id']), 'topic_info' => $topic, 'topic_posts' => $posts, 'can_reply' => $canReply, 'topic_pagination' => $topicPagination, 'topic_can_delete' => $canDelete, 'topic_can_nuke_or_restore' => $canNukeOrRestore, 'topic_can_bump' => $canBumpTopic, 'topic_can_lock' => $canLockTopic, ]);