'; /* ------------------------------- --- Znote AAC forum --- ------------------------------- Created by Znote. Version 1.4. Changelog (1.0 --> 1.2): - Updated to the new date/clock time system - Bootstrap design support. Changelog (1.2 --> 1.3): - Show character outfit as avatar - Show in-game position Changelog (1.3 -> 1.4): - Fix SQL query error when editing Board name. */ // BBCode rendering now lives in engine/function/bbcode.php as znote_bbcode(). function znote_forum_editor_assets() { static $loaded = false; if ($loaded) return; $loaded = true; $v = '3.2.1'; ?>

0) ? 'Up to ' . $max . ' image' . ($max === 1 ? '' : 's') . ' per post.' : 'Images are not allowed in forum posts.'; ?>

" picker plus the submit button. * * This used to be a fetchAll("SELECT `id`, `name`, `group_id` FROM `players` WHERE `level` >= 1 AND `account_id` = ?;", [$user_data['id']]); else $yourChars = db()->fetchAll("SELECT `id`, `name`, `group_id` FROM `players` WHERE `level` >= ? AND `account_id` = ?;", [(int)$config['forum']['level'], $user_data['id']]); if (!$yourChars) $yourChars = array(); $charCount = count($yourChars); $yourAccess = accountAccess($user_data['id'], znote_server_adapter()->normalizedEngine()); if ($admin) { if (!empty($_POST)) { $guilds = db()->fetchAll("SELECT `id`, `name` FROM `guilds` ORDER BY `name`;"); $guilds[] = array('id' => '0', 'name' => 'No guild'); } $yourAccess = 100; } // Your characters, indexed by char_id $charData = array(); foreach ($yourChars as $char) { $charData[$char['id']] = $char; if (get_character_guild_rank($char['id']) > 0) { $guild = get_player_guild_data($char['id']); $charData[$char['id']]['guild'] = $guild['guild_id']; $charData[$char['id']]['guild_rank'] = $guild['rank_level']; } else $charData[$char['id']]['guild'] = '0'; } $cooldownw = array( $user_znote_data['cooldown'], time(), $user_znote_data['cooldown'] - time() ); ///////////////// // Guild Leader & admin $leader = false; foreach($charData as $char) { if ($char['guild'] > 0 && $char['guild_rank'] == 3) $leader = true; } if ($admin && !empty($_POST) || $leader && !empty($_POST)) { $admin_thread_delete = getValue($_POST['admin_thread_delete'] ?? null); $admin_thread_close = getValue($_POST['admin_thread_close'] ?? null); $admin_thread_open = getValue($_POST['admin_thread_open'] ?? null); $admin_thread_sticky = getValue($_POST['admin_thread_sticky'] ?? null); $admin_thread_unstick = getValue($_POST['admin_thread_unstick'] ?? null); $admin_thread_id = getValue($_POST['admin_thread_id'] ?? null); // delete thread if ($admin_thread_delete !== false) { $admin_thread_id = (int)$admin_thread_id; $access = false; if (!$admin) { $thread = db()->fetchOne("SELECT `forum_id` FROM `znote_forum_threads` WHERE `id` = ?;", [$admin_thread_id]); $forum = db()->fetchOne("SELECT `guild_id` FROM `znote_forum` WHERE `id` = ?;", [$thread['forum_id']]); foreach($charData as $char) if ($char['guild'] == $forum['guild_id'] && $char['guild_rank'] == 3) $access = true; } else $access = true; if ($access) { // Delete all associated posts db()->execute("DELETE FROM `znote_forum_posts` WHERE `thread_id` = ?;", [$admin_thread_id]); // Delete thread itself db()->execute("DELETE FROM `znote_forum_threads` WHERE `id` = ? LIMIT 1;", [$admin_thread_id]); acp_log('forum.thread_delete', '#' . $admin_thread_id, ['scope' => $admin ? 'owner' : 'guild_leader']); echo '

'. t('forum.thread_deleted'). '

'; } else echo '

'. t('forum.perm_denied'). '

'; } // Close thread if ($admin_thread_close !== false) { $admin_thread_id = (int)$admin_thread_id; $access = false; if (!$admin) { $thread = db()->fetchOne("SELECT `forum_id` FROM `znote_forum_threads` WHERE `id` = ?;", [$admin_thread_id]); $forum = db()->fetchOne("SELECT `guild_id` FROM `znote_forum` WHERE `id` = ?;", [$thread['forum_id']]); foreach($charData as $char) if ($char['guild'] == $forum['guild_id'] && $char['guild_rank'] == 3) $access = true; } else $access = true; if ($access) { db()->execute("UPDATE `znote_forum_threads` SET `closed` = 1 WHERE `id` = ? LIMIT 1;", [$admin_thread_id]); acp_log('forum.thread_close', '#' . $admin_thread_id, ['scope' => $admin ? 'owner' : 'guild_leader']); echo '

'. t('forum.thread_closed'). '

'; } else echo '

'. t('forum.perm_denied'). '

'; } // open thread if ($admin_thread_open !== false) { $admin_thread_id = (int)$admin_thread_id; $access = false; if (!$admin) { $thread = db()->fetchOne("SELECT `forum_id` FROM `znote_forum_threads` WHERE `id` = ?;", [$admin_thread_id]); $forum = db()->fetchOne("SELECT `guild_id` FROM `znote_forum` WHERE `id` = ?;", [$thread['forum_id']]); foreach($charData as $char) if ($char['guild'] == $forum['guild_id'] && $char['guild_rank'] == 3) $access = true; } else $access = true; if ($access) { db()->execute("UPDATE `znote_forum_threads` SET `closed` = 0 WHERE `id` = ? LIMIT 1;", [$admin_thread_id]); acp_log('forum.thread_open', '#' . $admin_thread_id, ['scope' => $admin ? 'owner' : 'guild_leader']); echo '

'. t('forum.thread_opened'). '

'; } else echo '

'. t('forum.perm_denied2') .'

'; } // stick thread if ($admin_thread_sticky !== false) { $admin_thread_id = (int)$admin_thread_id; $access = false; if (!$admin) { $thread = db()->fetchOne("SELECT `forum_id` FROM `znote_forum_threads` WHERE `id` = ?;", [$admin_thread_id]); $forum = db()->fetchOne("SELECT `guild_id` FROM `znote_forum` WHERE `id` = ?;", [$thread['forum_id']]); foreach($charData as $char) if ($char['guild'] == $forum['guild_id'] && $char['guild_rank'] == 3) $access = true; } else $access = true; if ($access) { db()->execute("UPDATE `znote_forum_threads` SET `sticky` = 1 WHERE `id` = ? LIMIT 1;", [$admin_thread_id]); acp_log('forum.thread_sticky', '#' . $admin_thread_id, ['scope' => $admin ? 'owner' : 'guild_leader']); echo '

'. t('forum.thread_stuck2'). '

'; } else echo '

'. t('forum.perm_denied2') .'

'; } // unstick thread if ($admin_thread_unstick !== false) { $admin_thread_id = (int)$admin_thread_id; $access = false; if (!$admin) { $thread = db()->fetchOne("SELECT `forum_id` FROM `znote_forum_threads` WHERE `id` = ?;", [$admin_thread_id]); $forum = db()->fetchOne("SELECT `guild_id` FROM `znote_forum` WHERE `id` = ?;", [$thread['forum_id']]); foreach($charData as $char) if ($char['guild'] == $forum['guild_id'] && $char['guild_rank'] == 3) $access = true; } else $access = true; if ($access) { db()->execute("UPDATE `znote_forum_threads` SET `sticky` = 0 WHERE `id` = ? LIMIT 1;", [$admin_thread_id]); acp_log('forum.thread_unsticky', '#' . $admin_thread_id, ['scope' => $admin ? 'owner' : 'guild_leader']); echo '

'. t('forum.thread_unstuck2'). '

'; } else echo '

'. t('forum.perm_denied2') .'

'; } } ///////////////// // ADMIN FUNCT if ($admin && !empty($_POST)) { $admin_post_id = getValue($_POST['admin_post_id'] ?? null); $admin_post_delete = getValue($_POST['admin_post_delete'] ?? null); $admin_category_delete = getValue($_POST['admin_category_delete'] ?? null); $admin_category_edit = getValue($_POST['admin_category_edit'] ?? null); $admin_category_id = getValue($_POST['admin_category_id'] ?? null); $admin_update_category = getValue($_POST['admin_update_category'] ?? null); $admin_category_name = getValue($_POST['admin_category_name'] ?? null); $admin_category_access = getValue($_POST['admin_category_access'] ?? null); $admin_category_closed = getValue($_POST['admin_category_closed'] ?? null); $admin_category_hidden = getValue($_POST['admin_category_hidden'] ?? null); $admin_category_guild_id = getValue($_POST['admin_category_guild_id'] ?? null); if ($admin_category_access === false) $admin_category_access = 0; if ($admin_category_closed === false) $admin_category_closed = 0; if ($admin_category_hidden === false) $admin_category_hidden = 0; if ($admin_category_guild_id === false) $admin_category_guild_id = 0; $admin_board_create_name = getValue($_POST['admin_board_create_name'] ?? null); $admin_board_create_access = getValue($_POST['admin_board_create_access'] ?? null); $admin_board_create_closed = getValue($_POST['admin_board_create_closed'] ?? null); $admin_board_create_hidden = getValue($_POST['admin_board_create_hidden'] ?? null); $admin_board_create_guild_id = getValue($_POST['admin_board_create_guild_id'] ?? null); if ($admin_board_create_access === false) $admin_board_create_access = 0; if ($admin_board_create_closed === false) $admin_board_create_closed = 0; if ($admin_board_create_hidden === false) $admin_board_create_hidden = 0; if ($admin_board_create_guild_id === false) $admin_board_create_guild_id = 0; // Create board if ($admin_board_create_name !== false) { // Insert data db()->execute("INSERT INTO `znote_forum` (`name`, `access`, `closed`, `hidden`, `guild_id`) VALUES (?, ?, ?, ?, ?);", [ $admin_board_create_name, $admin_board_create_access, $admin_board_create_closed, $admin_board_create_hidden, $admin_board_create_guild_id, ]); acp_log('forum.board_create', (string)$admin_board_create_name, ['access' => $admin_board_create_access, 'guild_id' => $admin_board_create_guild_id]); echo '

'. t('forum.board_created'). '

'; } ////////////////// // update category if ($admin_update_category !== false) { $admin_category_id = (int)$admin_category_id; // Update the category db()->execute("UPDATE `znote_forum` SET `name` = ?, `access` = ?, `closed` = ?, `hidden` = ?, `guild_id` = ? WHERE `id` = ? LIMIT 1;", [ $admin_category_name, $admin_category_access, $admin_category_closed, $admin_category_hidden, $admin_category_guild_id, $admin_category_id, ]); acp_log('forum.board_update', '#' . $admin_category_id, ['access' => $admin_category_access, 'guild_id' => $admin_category_guild_id]); echo '

'. t('forum.board_updated'). '

'; } ////////////////// // edit category if ($admin_category_edit !== false) { $admin_category_id = (int)$admin_category_id; $category = db()->fetchOne("SELECT `id`, `name`, `access`, `closed`, `hidden`, `guild_id` FROM `znote_forum` WHERE `id` = ? LIMIT 1;", [$admin_category_id]); if ($category !== false) { ?>
'. t('forum.cat_not_found'). ''; } // delete category if ($admin_category_delete !== false) { $admin_category_id = (int)$admin_category_id; // find all threads in category $threads = db()->fetchAll("SELECT `id` FROM `znote_forum_threads` WHERE `forum_id` = ?;", [$admin_category_id]); // Then loop through all threads, and delete all associated posts: foreach($threads as $thread) { db()->execute("DELETE FROM `znote_forum_posts` WHERE `thread_id` = ?;", [$thread['id']]); } // Then delete all threads db()->execute("DELETE FROM `znote_forum_threads` WHERE `forum_id` = ?;", [$admin_category_id]); // Then delete the category db()->execute("DELETE FROM `znote_forum` WHERE `id` = ? LIMIT 1;", [$admin_category_id]); acp_log('forum.board_delete', '#' . $admin_category_id); echo '

' . t('forum.board_and_threads_deleted') . '

'; } // delete post if ($admin_post_delete !== false) { $admin_post_id = (int)$admin_post_id; // Delete the post db()->execute("DELETE FROM `znote_forum_posts` WHERE `id` = ? LIMIT 1;", [$admin_post_id]); acp_log('forum.post_delete', '#' . $admin_post_id); echo '

'. t('forum.post_deleted'). '

'; } } // End admin function // Fetching get values if (!empty($_GET)) { $getCat = getValue($_GET['cat'] ?? null); $getForum = getValue($_GET['forum'] ?? null); $getThread = getValue($_GET['thread'] ?? null); $new_thread_category = getValue($_POST['new_thread_category'] ?? null); $new_thread_cid = getValue($_POST['new_thread_cid'] ?? null); $create_thread_cid = getValue($_POST['create_thread_cid'] ?? null); $create_thread_title = getValue($_POST['create_thread_title'] ?? null); $create_thread_text = getValue($_POST['create_thread_text'] ?? null); $create_thread_category = getValue($_POST['create_thread_category'] ?? null); $update_thread_id = getValue($_POST['update_thread_id'] ?? null); $update_thread_title = getValue($_POST['update_thread_title'] ?? null); $update_thread_text = getValue($_POST['update_thread_text'] ?? null); $edit_thread = getValue($_POST['edit_thread'] ?? null); $edit_thread_id = getValue($_POST['edit_thread_id'] ?? null); $reply_thread = getValue($_POST['reply_thread'] ?? null); $reply_text = getValue($_POST['reply_text'] ?? null); $reply_cid = getValue($_POST['reply_cid'] ?? null); $edit_post = getValue($_POST['edit_post'] ?? null); $edit_post_id = getValue($_POST['edit_post_id'] ?? null); $update_post_id = getValue($_POST['update_post_id'] ?? null); $update_post_text = getValue($_POST['update_post_text'] ?? null); // Image cap. The editor checks this too, but that check is a convenience - // this one is the rule, because a POST does not have to come from the editor. // Blanking the field makes the save branches below skip, since each requires // its text to be !== false. $forumImageLimit = (int)($config['forum']['maxImagesPerPost'] ?? 1); $forumImageDenied = false; foreach (array('create_thread_text', 'update_thread_text', 'reply_text', 'update_post_text') as $forumField) { if ($$forumField !== false && znote_bbcode_count_images($$forumField) > $forumImageLimit) { $forumImageDenied = true; $$forumField = false; } } if ($forumImageDenied) { echo '

' . ($forumImageLimit > 0 ? 'Too many images: only ' . $forumImageLimit . ' allowed per post. Nothing was saved.' : 'Images are not allowed in forum posts. Nothing was saved.') . '

'; } ///////////////////// // When you are POSTING in an existing thread if ($reply_thread !== false && $reply_text !== false && $reply_cid !== false) { $reply_cid = (int)$reply_cid; if ($user_znote_data['cooldown'] < time()) { user_update_znote_account(array('cooldown'=>(time() + $config['forum']['cooldownPost']))); $thread = db()->fetchOne("SELECT `closed` FROM `znote_forum_threads` WHERE `id` = ? LIMIT 1;", [$reply_thread]); if (!is_array($thread) || !isset($charData[$reply_cid])) $access = false; else if ($thread['closed'] == 1 && $admin === false) $access = false; else $access = true; if ($access) { db()->execute("INSERT INTO `znote_forum_posts` (`thread_id`, `player_id`, `player_name`, `text`, `created`, `updated`) VALUES (?, ?, ?, ?, ?, ?);", [$reply_thread, $reply_cid, $charData[$reply_cid]['name'], $reply_text, time(), time()]); if ($config['forum']['newPostsBumpThreads']) db()->execute("UPDATE `znote_forum_threads` SET `updated` = ? WHERE `id` = ?;", [time(), $reply_thread]); } else echo '

You don\'t have permission to post on this thread. [Thread: Closed]

'; } else { ?>

seconds before you can create or post.

(time() + $config['forum']['cooldownCreate']))); $category = db()->fetchOne("SELECT `access`, `closed`, `guild_id` FROM `znote_forum` WHERE `id` = ? LIMIT 1;", [$create_thread_category]); if ($category !== false) { $access = true; if (!$admin) { if ($category['access'] > $yourAccess) $access = false; if ($category['guild_id'] > 0) { $status = false; foreach($charData as $char) { if ($char['guild'] == $category['guild_id']) $status = true; } if (!$status) $access = false; } if ($category['closed'] > 0) $access = false; } if ($access) { db()->execute("INSERT INTO `znote_forum_threads` (`forum_id`, `player_id`, `player_name`, `title`, `text`, `created`, `updated`, `sticky`, `hidden`, `closed`) VALUES (?, ?, ?, ?, ?, ?, ?, 0, 0, 0);", [ $create_thread_category, $create_thread_cid, $charData[$create_thread_cid]['name'], $create_thread_title, $create_thread_text, time(), time(), ]); SendGet(array('cat'=>$create_thread_category), 'forum.php'); } else echo '

'. t('forum.perm_thread'). '

'; } else echo t('forum.cat_missing'); } else { ?>

seconds before you can create or post.

fetchOne("SELECT `id`, `player_name`, `text`, `thread_id` FROM `znote_forum_posts` WHERE `id` = ? LIMIT 1;", [$update_post_id]); if (!is_array($post)) $post = array('id' => 0, 'player_name' => '', 'text' => '', 'thread_id' => 0); $thread = db()->fetchOne("SELECT `closed` FROM `znote_forum_threads` WHERE `id` = ? LIMIT 1;", [$post['thread_id']]); // Verify access $access = PlayerHaveAccess($yourChars, $post['player_name']); if ($thread !== false && $thread['closed'] == 1 && $admin === false) $access = false; if ($admin) $access = true; //if ($thread === false) $access = false; if ($access) { db()->execute("UPDATE `znote_forum_posts` SET `text` = ?, `updated` = ? WHERE `id` = ?;", [$update_post_text, time(), $update_post_id]); if ($admin) acp_log('forum.post_update', '#' . (int)$update_post_id); echo '

' . t('forum.post_updated') . '

'; } else echo "

" . t('forum.edit_post_denied') . "

"; } ///////////////////// // When you ARE updating thread if ($update_thread_id !== false && $update_thread_title !== false && $update_thread_text !== false) { // Fetch the thread data $thread = db()->fetchOne("SELECT `id`, `player_name`, `title`, `text`, `closed` FROM `znote_forum_threads` WHERE `id` = ? LIMIT 1;", [$update_thread_id]); if (!is_array($thread)) $thread = array('id' => 0, 'player_name' => '', 'title' => '', 'text' => '', 'closed' => 0); // Verify access $access = PlayerHaveAccess($yourChars, $thread['player_name']); if ($thread['closed'] == 1 && $admin === false) $access = false; if ($admin) $access = true; if ($access) { db()->execute("UPDATE `znote_forum_threads` SET `title` = ?, `text` = ? WHERE `id` = ?;", [$update_thread_title, $update_thread_text, $update_thread_id]); if ($admin) acp_log('forum.thread_update', '#' . (int)$update_thread_id, ['title' => (string)$update_thread_title]); echo '

'. t('forum.thread_updated'). '

'; } else echo "

" . t('forum.edit_thread_denied') . "

"; } ///////////////////// // When you want to edit a post if ($edit_post_id !== false && $edit_post !== false) { // Fetch the post data $post = db()->fetchOne("SELECT `id`, `thread_id`, `text`, `player_name` FROM `znote_forum_posts` WHERE `id` = ? LIMIT 1;", [$edit_post_id]); if (!is_array($post)) $post = array('id' => 0, 'thread_id' => 0, 'text' => '', 'player_name' => ''); $thread = db()->fetchOne("SELECT `closed` FROM `znote_forum_threads` WHERE `id` = ? LIMIT 1;", [$post['thread_id']]); if (!is_array($thread)) $thread = array('closed' => 0); // Verify access $access = PlayerHaveAccess($yourChars, $post['player_name']); if ($thread['closed'] == 1 && $admin === false) $access = false; if ($admin) $access = true; if ($access) { ?>

'. t('forum.no_edit_post') .'

'; } else ///////////////////// // When you want to edit a thread if ($edit_thread_id !== false && $edit_thread !== false) { // Fetch the thread data $thread = db()->fetchOne("SELECT `id`, `title`, `text`, `player_name`, `closed` FROM `znote_forum_threads` WHERE `id` = ? LIMIT 1;", [$edit_thread_id]); $access = PlayerHaveAccess($yourChars, $thread['player_name']); if ($thread['closed'] == 1) $access = false; if ($admin) $access = true; if ($access) { ?>



'. t('forum.edit_denied'). '

'; } else ///////////////////// // When you want to view a thread if ($getThread !== false) { $getThread = (int)$getThread; $threadData = db()->fetchOne("SELECT `id`, `forum_id`, `player_id`, `player_name`, `title`, `text`, `created`, `updated`, `sticky`, `hidden`, `closed` FROM `znote_forum_threads` WHERE `id` = ? LIMIT 1;", [$getThread]); if ($threadData !== false) { $category = db()->fetchOne("SELECT `hidden`, `access`, `guild_id` FROM `znote_forum` WHERE `id` = ? LIMIT 1;", [$threadData['forum_id']]); if ($category === false) die("Thread category does not exist."); $access = true; $leader = false; if ($category['hidden'] == 1 || $category['access'] > 1 || $category['guild_id'] > 0) { $access = false; if ($category['hidden'] == 1) $access = PlayerHaveAccess($yourChars, $threadData['player_name']); if ($category['access'] > 1 && $yourAccess >= $category['access']) $access = true; foreach($charData as $char) { if ($category['guild_id'] == $char['guild']) $access = true; if ($char['guild_rank'] == 3) $leader = true; } if ($admin) $access = true; } if ($access) { $threadPlayer = ($config['forum']['outfit_avatars'] || $config['forum']['player_position']) ? db()->fetchOne("SELECT `id`, `group_id`, `sex`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons` FROM `players` WHERE `id` = ?;", [$threadData['player_id']]) : false; ?>

". $threadData['title'] .""; ?>

img
0 && ($threadData['closed'] == 0 || $yourAccess > 3)): ?>
fetchAll("SELECT `id`, `player_id`, `player_name`, `text`, `created`, `updated` FROM `znote_forum_posts` WHERE `thread_id` = ? ORDER BY `created`;", [$threadData['id']]); if ($posts !== false) { // Load extra data (like outfit avatars?) $players = array(); $extra = false; if ($config['forum']['outfit_avatars'] || $config['forum']['player_position']) { $extra = true; foreach($posts as $post) if (!isset($players[$post['player_id']])) $players[$post['player_id']] = array(); $playerIds = array_keys($players); $playerIdPlaceholders = implode(',', array_fill(0, count($playerIds), '?')); $sql_players = db()->fetchAll("SELECT `id`, `group_id`, `sex`, `lookbody`, `lookfeet`, `lookhead`, `looklegs`, `looktype`, `lookaddons` FROM `players` WHERE `id` IN ({$playerIdPlaceholders});", $playerIds); foreach ($sql_players as $player) $players[$player['id']] = $player; } foreach($posts as $post) { ?>
img
0 && ($threadData['closed'] == 0 || $yourAccess > 3)) { ?>
0) { if ($threadData['closed'] == 0 || $yourAccess > 3) { ?>

' . t('forum.thread_closed_note') . '

'; } else { ?>

(int)$config['forum']['level']]) ?>

' . t('forum.perm_denied3') . '

'; } else { ?>

0 && !empty($_GET['forum'])) { $tmpCat = getValue($_GET['cat'] ?? null); $tmpCatName = getValue($_GET['forum'] ?? null); ?>


fetchOne("SELECT `access`, `closed`, `guild_id` FROM `znote_forum` WHERE `id` = ? LIMIT 1;", [$new_thread_category]); if ($category !== false) { $access = true; if (!$admin) { if ($category['access'] > $yourAccess) $access = false; if ($category['guild_id'] > 0) { $status = false; foreach($charData as $char) { if ($char['guild'] == $category['guild_id']) $status = true; } if (!$status) $access = false; } if ($category['closed'] > 0) $access = false; } if ($access) { ?>

Cancel
'. t('forum.perm_thread'). '

'; } } else ///////////////////// // When category is specified if ($getCat !== false) { $getCat = (int)$getCat; // Fetch category rules $category = db()->fetchOne("SELECT `name`, `access`, `closed`, `hidden`, `guild_id` FROM `znote_forum` WHERE `id` = ? AND `access` <= ? LIMIT 1;", [$getCat, $yourAccess]); if ($category !== false && $category['guild_id'] > 0 && !$admin) { $access = false; foreach($charData as $char) if ($category['guild_id'] == $char['guild']) $access = true; if ($access !== true) $category = false; } if ($category !== false) { $getCatInt = (int)$getCat; echo ''; echo '

' . znote_forum_e($category['name']) . '

'; $threads = db()->fetchAll( "SELECT `t`.`id`, `t`.`player_name`, `t`.`title`, `t`.`sticky`, `t`.`closed`, `t`.`created`, `t`.`updated`, " . "COUNT(`p`.`id`) AS `reply_count`, COALESCE(MAX(`p`.`created`), 0) AS `last_reply_at` " . "FROM `znote_forum_threads` `t` LEFT JOIN `znote_forum_posts` `p` ON `p`.`thread_id` = `t`.`id` " . "WHERE `t`.`forum_id` = ? " . "GROUP BY `t`.`id`, `t`.`player_name`, `t`.`title`, `t`.`sticky`, `t`.`closed`, `t`.`created`, `t`.`updated` " . "ORDER BY `t`.`sticky` DESC, `t`.`updated` DESC;", [$getCatInt] ); $lastReplyBy = array(); $lrRows = db()->fetchAll( "SELECT `x`.`thread_id`, `x`.`player_name` FROM `znote_forum_posts` `x` JOIN (" . "SELECT `p2`.`thread_id`, MAX(`p2`.`created`) AS `mc` FROM `znote_forum_posts` `p2` " . "JOIN `znote_forum_threads` `t2` ON `t2`.`id` = `p2`.`thread_id` WHERE `t2`.`forum_id` = ? " . "GROUP BY `p2`.`thread_id`) `y` ON `y`.`thread_id` = `x`.`thread_id` AND `y`.`mc` = `x`.`created`;", [$getCatInt] ); foreach ((array)$lrRows as $row) if (!isset($lastReplyBy[$row['thread_id']])) $lastReplyBy[$row['thread_id']] = $row['player_name']; $visibleThreads = array(); foreach ((array)$threads as $thread) { $access = true; if ($category['hidden'] == 1) { $access = PlayerHaveAccess($yourChars, $thread['player_name']); if ($yourAccess > 3 || $admin) $access = true; } if ($access) $visibleThreads[] = $thread; } ?>

$e($thread['player_name']), 'ago' => znote_forum_ago($thread['created']))); ?>
0 ? t('forum.last_by', array('name' => $e($replyBy), 'ago' => znote_forum_ago($thread['last_reply_at']))) : t('forum.no_replies'); ?>
0) { if ($category['closed'] == 0 || $admin) { ?>
'. t('forum.board_closed'). '

'; } else echo '

'. t('forum.level_required_new_thread', ['level' => (int)$config['forum']['level']]) .'

'; } else echo '

'. t('forum.board_access_denied', ['level' => (int)$config['forum']['level']]) .'

'; } } else { ////////////////////// // No category specified, show list of available categories $boardWhereParams = []; if ($admin) { $boardWhere = ''; } else { $boardWhere = " WHERE `f`.`access` <= ?"; $boardWhereParams[] = (int)$yourAccess; } $categories = db()->fetchAll( "SELECT `f`.`id`, `f`.`name`, `f`.`access`, `f`.`closed`, `f`.`hidden`, `f`.`guild_id`, " . "COUNT(`t`.`id`) AS `thread_count`, COALESCE(MAX(`t`.`updated`), 0) AS `last_time` " . "FROM `znote_forum` `f` LEFT JOIN `znote_forum_threads` `t` ON `t`.`forum_id` = `f`.`id`" . $boardWhere . " GROUP BY `f`.`id`, `f`.`name`, `f`.`access`, `f`.`closed`, `f`.`hidden`, `f`.`guild_id` ORDER BY `f`.`name`;", $boardWhereParams ); $lastThreads = array(); $ltRows = db()->fetchAll( "SELECT `x`.`forum_id`, `x`.`player_name`, `x`.`title`, `x`.`id` FROM `znote_forum_threads` `x` " . "JOIN (SELECT `forum_id`, MAX(`updated`) AS `mu` FROM `znote_forum_threads` GROUP BY `forum_id`) `y` " . "ON `y`.`forum_id` = `x`.`forum_id` AND `y`.`mu` = `x`.`updated`;" ); foreach ((array)$ltRows as $row) if (!isset($lastThreads[$row['forum_id']])) $lastThreads[$row['forum_id']] = $row; $guild = false; foreach ($charData as $char) if ($char['guild'] > 0) $guild = true; if (!isset($guilds)) { $guilds = db()->fetchAll("SELECT `id`, `name` FROM `guilds` ORDER BY `name`;"); $guilds[] = array('id' => '0', 'name' => 'No guild'); } $guildName = array(); foreach ((array)$guilds as $g) $guildName[$g['id']] = $g['name']; $mainBoards = array(); $guildboard = array(); foreach ((array)$categories as $b) { $li = $lastThreads[$b['id']] ?? null; $b['last_author'] = $li['player_name'] ?? ''; $b['last_title'] = $li['title'] ?? ''; if ((int)$b['guild_id'] > 0) { $inGuild = $admin; foreach ($charData as $char) if ((int)$b['guild_id'] === (int)$char['guild']) $inGuild = true; if ($inGuild) $guildboard[] = $b; } else { $mainBoards[] = $b; } } $znfBoardRow = static function (array $b) use ($admin, $guildName) { $e = 'znote_forum_e'; $id = (int)$b['id']; ?>
0 ? '⚔' : '💬'; ?> 0): ?> · ·


'; theme_close(); ?>