Cleaned up forum index, listing and topic page as well as added read tracking.
This commit is contained in:
parent
cd9e72d3c0
commit
8b2e174d40
10 changed files with 412 additions and 288 deletions
|
@ -63,6 +63,10 @@
|
|||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&--unread {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
&__stats {
|
||||
|
@ -88,6 +92,7 @@
|
|||
|
||||
&__activity {
|
||||
min-width: 270px;
|
||||
min-height: 50px;
|
||||
align-items: center;
|
||||
|
||||
@media (max-width: @mio-forum-listing-mobile) {
|
||||
|
|
|
@ -34,7 +34,6 @@ function migrate_up(PDO $conn): void
|
|||
`topic_bumped` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`topic_deleted` TIMESTAMP NULL DEFAULT NULL,
|
||||
`topic_locked` TIMESTAMP NULL DEFAULT NULL,
|
||||
`topic_view_count` INT(10) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`topic_id`),
|
||||
INDEX `topics_forum_id_foreign` (`forum_id`),
|
||||
INDEX `topics_user_id_foreign` (`user_id`),
|
||||
|
@ -86,33 +85,16 @@ function migrate_up(PDO $conn): void
|
|||
)
|
||||
");
|
||||
|
||||
$conn->exec("
|
||||
CREATE TABLE `msz_forum_categories_track` (
|
||||
`user_id` INT(10) UNSIGNED NOT NULL,
|
||||
`forum_id` INT(10) UNSIGNED NOT NULL,
|
||||
`track_last_read` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX `categories_track_forum_id_foreign` (`forum_id`),
|
||||
INDEX `categories_track_user_id_foreign` (`user_id`),
|
||||
CONSTRAINT `categories_track_forum_id_foreign`
|
||||
FOREIGN KEY (`forum_id`)
|
||||
REFERENCES `msz_forum_categories` (`forum_id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT `categories_track_user_id_foreign`
|
||||
FOREIGN KEY (`user_id`)
|
||||
REFERENCES `msz_users` (`user_id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE
|
||||
)
|
||||
");
|
||||
|
||||
$conn->exec("
|
||||
CREATE TABLE `msz_forum_topics_track` (
|
||||
`user_id` INT(10) UNSIGNED NOT NULL,
|
||||
`topic_id` INT(10) UNSIGNED NOT NULL,
|
||||
`forum_id` INT(10) UNSIGNED NOT NULL,
|
||||
`track_last_read` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX `topics_track_topic_id_foreign` (`topic_id`),
|
||||
INDEX `topics_track_user_id_foreign` (`user_id`),
|
||||
UNIQUE INDEX `topics_track_unique` (`user_id`, `topic_id`),
|
||||
INDEX `topics_track_topic_id_foreign` (`topic_id`),
|
||||
INDEX `topics_track_user_id_foreign` (`user_id`),
|
||||
INDEX `topics_track_forum_id_foreign` (`forum_id`),
|
||||
CONSTRAINT `topics_track_topic_id_foreign`
|
||||
FOREIGN KEY (`topic_id`)
|
||||
REFERENCES `msz_forum_topics` (`topic_id`)
|
||||
|
@ -122,6 +104,11 @@ function migrate_up(PDO $conn): void
|
|||
FOREIGN KEY (`user_id`)
|
||||
REFERENCES `msz_users` (`user_id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE,
|
||||
CONSTRAINT `topics_track_forum_id_foreign`
|
||||
FOREIGN KEY (`forum_id`)
|
||||
REFERENCES `msz_forum_categories` (`forum_id`)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE
|
||||
)
|
||||
");
|
||||
|
|
|
@ -12,22 +12,8 @@ if ($forumId === 0) {
|
|||
exit;
|
||||
}
|
||||
|
||||
$db = Database::connection();
|
||||
$templating = $app->getTemplating();
|
||||
|
||||
$getForum = $db->prepare('
|
||||
SELECT
|
||||
`forum_id`, `forum_name`, `forum_type`, `forum_link`, `forum_link_clicks`, `forum_parent`,
|
||||
(
|
||||
SELECT COUNT(`topic_id`)
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
) as `forum_topic_count`
|
||||
FROM `msz_forum_categories` as f
|
||||
WHERE `forum_id` = :forum_id
|
||||
');
|
||||
$getForum->bindValue('forum_id', $forumId);
|
||||
$forum = $getForum->execute() ? $getForum->fetch() : [];
|
||||
$forum = forum_fetch($forumId);
|
||||
|
||||
if (empty($forum) || ($forum['forum_type'] == MSZ_FORUM_TYPE_LINK && empty($forum['forum_link']))) {
|
||||
http_response_code(404);
|
||||
|
@ -41,114 +27,15 @@ if ($forum['forum_type'] == MSZ_FORUM_TYPE_LINK) {
|
|||
return;
|
||||
}
|
||||
|
||||
// declare this, templating engine assumes it exists
|
||||
$topics = [];
|
||||
$topics = forum_may_have_topics($forum['forum_type'])
|
||||
? forum_topic_listing($forum['forum_id'], $app->getUserId(), $topicsOffset, $topicsRange)
|
||||
: [];
|
||||
|
||||
// no need to fetch topics for categories (or links but we're already done with those at this point)
|
||||
if ($forum['forum_type'] == MSZ_FORUM_TYPE_DISCUSSION) {
|
||||
$getTopics = $db->prepare('
|
||||
SELECT
|
||||
t.`topic_id`, t.`topic_title`, t.`topic_view_count`, t.`topic_locked`, t.`topic_type`, t.`topic_created`,
|
||||
au.`user_id` as `author_id`, au.`username` as `author_name`,
|
||||
COALESCE(ar.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `author_colour`,
|
||||
lp.`post_id` as `response_id`,
|
||||
lp.`post_created` as `response_created`,
|
||||
lu.`user_id` as `respondent_id`,
|
||||
lu.`username` as `respondent_name`,
|
||||
COALESCE(lr.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `respondent_colour`,
|
||||
(
|
||||
SELECT COUNT(`post_id`)
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
) as `topic_post_count`
|
||||
FROM `msz_forum_topics` as t
|
||||
LEFT JOIN `msz_users` as au
|
||||
ON t.`user_id` = au.`user_id`
|
||||
LEFT JOIN `msz_roles` as ar
|
||||
ON ar.`role_id` = au.`display_role`
|
||||
LEFT JOIN `msz_forum_posts` as lp
|
||||
ON lp.`post_id` = (
|
||||
SELECT `post_id`
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
ORDER BY `post_id` DESC
|
||||
LIMIT 1
|
||||
)
|
||||
LEFT JOIN `msz_users` as lu
|
||||
ON lu.`user_id` = lp.`user_id`
|
||||
LEFT JOIN `msz_roles` as lr
|
||||
ON lr.`role_id` = lu.`display_role`
|
||||
WHERE t.`forum_id` = :forum_id
|
||||
AND t.`topic_deleted` IS NULL
|
||||
ORDER BY t.`topic_type` DESC, t.`topic_bumped` DESC
|
||||
LIMIT :offset, :take
|
||||
');
|
||||
$getTopics->bindValue('forum_id', $forum['forum_id']);
|
||||
$getTopics->bindValue('offset', $topicsOffset);
|
||||
$getTopics->bindValue('take', $topicsRange);
|
||||
$topics = $getTopics->execute() ? $getTopics->fetchAll() : $topics;
|
||||
}
|
||||
$forum['forum_subforums'] = forum_get_children($forum['forum_id'], $app->getUserId());
|
||||
|
||||
$getSubforums = $db->prepare('
|
||||
SELECT
|
||||
f.`forum_id`, f.`forum_name`, f.`forum_description`, f.`forum_type`, f.`forum_link`, f.`forum_archived`,
|
||||
t.`topic_id` as `recent_topic_id`, p.`post_id` as `recent_post_id`,
|
||||
t.`topic_title` as `recent_topic_title`,
|
||||
p.`post_created` as `recent_post_created`,
|
||||
u.`user_id` as `recent_post_user_id`,
|
||||
u.`username` as `recent_post_username`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `recent_post_user_colour`,
|
||||
(
|
||||
SELECT COUNT(t.`topic_id`)
|
||||
FROM `msz_forum_topics` as t
|
||||
WHERE t.`forum_id` = f.`forum_id`
|
||||
) as `forum_topic_count`,
|
||||
(
|
||||
SELECT COUNT(p.`post_id`)
|
||||
FROM `msz_forum_posts` as p
|
||||
WHERE p.`forum_id` = f.`forum_id`
|
||||
) as `forum_post_count`
|
||||
FROM `msz_forum_categories` as f
|
||||
LEFT JOIN `msz_forum_topics` as t
|
||||
ON t.`topic_id` = (
|
||||
SELECT `topic_id`
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
AND `topic_deleted` IS NULL
|
||||
ORDER BY `topic_bumped` DESC
|
||||
LIMIT 1
|
||||
)
|
||||
LEFT JOIN `msz_forum_posts` as p
|
||||
ON p.`post_id` = (
|
||||
SELECT `post_id`
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
ORDER BY `post_id` DESC
|
||||
LIMIT 1
|
||||
)
|
||||
LEFT JOIN `msz_users` as u
|
||||
ON u.`user_id` = p.`user_id`
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON r.`role_id` = u.`display_role`
|
||||
WHERE `forum_parent` = :forum_id
|
||||
AND `forum_hidden` = false
|
||||
');
|
||||
$getSubforums->bindValue('forum_id', $forum['forum_id']);
|
||||
$forum['forum_subforums'] = $getSubforums->execute() ? $getSubforums->fetchAll() : [];
|
||||
|
||||
if (count($forum['forum_subforums']) > 0) {
|
||||
// this really, really needs a better name
|
||||
$getSubSubs = $db->prepare('
|
||||
SELECT `forum_id`, `forum_name`
|
||||
FROM `msz_forum_categories`
|
||||
WHERE `forum_parent` = :forum_id
|
||||
AND `forum_hidden` = false
|
||||
');
|
||||
|
||||
foreach ($forum['forum_subforums'] as $skey => $subforum) {
|
||||
$getSubSubs->bindValue('forum_id', $subforum['forum_id']);
|
||||
$forum['forum_subforums'][$skey]['forum_subforums'] = $getSubSubs->execute() ? $getSubSubs->fetchAll() : [];
|
||||
}
|
||||
foreach ($forum['forum_subforums'] as $skey => $subforum) {
|
||||
$forum['forum_subforums'][$skey]['forum_subforums']
|
||||
= forum_get_children($subforum['forum_id'], $app->getUserId(), true);
|
||||
}
|
||||
|
||||
echo $app->getTemplating()->render('forum.forum', [
|
||||
|
|
|
@ -3,100 +3,21 @@ use Misuzu\Database;
|
|||
|
||||
require_once __DIR__ . '/../../misuzu.php';
|
||||
|
||||
$db = Database::connection();
|
||||
|
||||
$categories = $db->query('
|
||||
SELECT
|
||||
f.`forum_id`, f.`forum_name`, f.`forum_type`,
|
||||
(
|
||||
SELECT COUNT(`forum_id`)
|
||||
FROM `msz_forum_categories` as sf
|
||||
WHERE sf.`forum_parent` = f.`forum_id`
|
||||
) as `forum_children`
|
||||
FROM `msz_forum_categories` as f
|
||||
WHERE f.`forum_parent` = 0
|
||||
AND f.`forum_type` = 1
|
||||
AND f.`forum_hidden` = false
|
||||
ORDER BY f.`forum_order`
|
||||
')->fetchAll();
|
||||
|
||||
$categories = array_merge([
|
||||
[
|
||||
'forum_id' => 0,
|
||||
'forum_name' => 'Forums',
|
||||
'forum_children' => 0,
|
||||
'forum_type' => 1,
|
||||
],
|
||||
], $categories);
|
||||
|
||||
$getSubCategories = $db->prepare('
|
||||
SELECT
|
||||
f.`forum_id`, f.`forum_name`, f.`forum_description`, f.`forum_type`,
|
||||
f.`forum_link`, f.`forum_link_clicks`, f.`forum_archived`,
|
||||
t.`topic_id` as `recent_topic_id`, p.`post_id` as `recent_post_id`,
|
||||
t.`topic_title` as `recent_topic_title`,
|
||||
p.`post_created` as `recent_post_created`,
|
||||
u.`user_id` as `recent_post_user_id`,
|
||||
u.`username` as `recent_post_username`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `recent_post_user_colour`,
|
||||
(
|
||||
SELECT COUNT(`topic_id`)
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
) as `forum_topic_count`,
|
||||
(
|
||||
SELECT COUNT(`post_id`)
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
) as `forum_post_count`
|
||||
FROM `msz_forum_categories` as f
|
||||
LEFT JOIN `msz_forum_topics` as t
|
||||
ON t.`topic_id` = (
|
||||
SELECT `topic_id`
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
AND `topic_deleted` IS NULL
|
||||
ORDER BY `topic_bumped` DESC
|
||||
LIMIT 1
|
||||
)
|
||||
LEFT JOIN `msz_forum_posts` as p
|
||||
ON p.`post_id` = (
|
||||
SELECT `post_id`
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
ORDER BY `post_id` DESC
|
||||
LIMIT 1
|
||||
)
|
||||
LEFT JOIN `msz_users` as u
|
||||
ON u.`user_id` = p.`user_id`
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON r.`role_id` = u.`display_role`
|
||||
WHERE f.`forum_parent` = :forum_id
|
||||
AND f.`forum_hidden` = false
|
||||
AND ((f.`forum_parent` = 0 AND f.`forum_type` != 1) OR f.`forum_parent` != 0)
|
||||
ORDER BY f.`forum_order`
|
||||
');
|
||||
$categories = forum_get_root_categories();
|
||||
|
||||
foreach ($categories as $key => $category) {
|
||||
// replace these magic numbers with a constant later, only categories and discussion forums may have subs
|
||||
if (!in_array($category['forum_type'], [0, 1])
|
||||
&& ($category['forum_id'] === 0 || $category['forum_children'] > 0)) {
|
||||
continue;
|
||||
}
|
||||
$categories[$key]['forum_subforums'] = forum_get_children($category['forum_id'], $app->getUserId());
|
||||
|
||||
$getSubCategories->bindValue('forum_id', $category['forum_id']);
|
||||
$categories[$key]['forum_subforums'] = $getSubCategories->execute() ? $getSubCategories->fetchAll() : [];
|
||||
|
||||
// one level down more!
|
||||
foreach ($categories[$key]['forum_subforums'] as $skey => $sub) {
|
||||
$getSubCategories->bindValue('forum_id', $sub['forum_id']);
|
||||
if (!forum_may_have_children($sub['forum_type'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$categories[$key]['forum_subforums'][$skey]['forum_subforums']
|
||||
= $getSubCategories->execute() ? $getSubCategories->fetchAll() : [];
|
||||
= forum_get_children($sub['forum_id'], $app->getUserId(), true);
|
||||
}
|
||||
}
|
||||
|
||||
$categories[0]['forum_children'] = count($categories[0]['forum_subforums']);
|
||||
|
||||
echo $app->getTemplating()->render('forum.index', [
|
||||
'forum_categories' => $categories,
|
||||
]);
|
||||
|
|
|
@ -125,6 +125,7 @@ if ($postRequest) {
|
|||
IPAddress::remote()->getString(),
|
||||
$postText
|
||||
);
|
||||
forum_topic_mark_read($app->getUserId(), $topicId, $forum['forum_id']);
|
||||
|
||||
header("Location: /forum/topic.php?p={$postId}#p{$postId}");
|
||||
return;
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
<?php
|
||||
use Misuzu\Database;
|
||||
|
||||
require_once __DIR__ . '/../../misuzu.php';
|
||||
|
||||
$db = Database::connection();
|
||||
$templating = $app->getTemplating();
|
||||
|
||||
$postId = (int)($_GET['p'] ?? 0);
|
||||
|
@ -11,7 +8,6 @@ $topicId = (int)($_GET['t'] ?? 0);
|
|||
$postsOffset = max((int)($_GET['o'] ?? 0), 0);
|
||||
$postsRange = max(min((int)($_GET['r'] ?? 10), 25), 5);
|
||||
|
||||
// find topic id
|
||||
if ($topicId < 1 && $postId > 0) {
|
||||
$postInfo = forum_post_find($postId);
|
||||
|
||||
|
@ -21,28 +17,7 @@ if ($topicId < 1 && $postId > 0) {
|
|||
}
|
||||
}
|
||||
|
||||
$getTopic = $db->prepare('
|
||||
SELECT
|
||||
t.`topic_id`, t.`forum_id`, t.`topic_title`, t.`topic_type`, t.`topic_locked`,
|
||||
f.`forum_archived` as `topic_archived`,
|
||||
(
|
||||
SELECT MIN(`post_id`)
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
) as `topic_first_post_id`,
|
||||
(
|
||||
SELECT COUNT(`post_id`)
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
) as `topic_post_count`
|
||||
FROM `msz_forum_topics` as t
|
||||
LEFT JOIN `msz_forum_categories` as f
|
||||
ON f.`forum_id` = t.`forum_id`
|
||||
WHERE t.`topic_id` = :topic_id
|
||||
AND t.`topic_deleted` IS NULL
|
||||
');
|
||||
$getTopic->bindValue('topic_id', $topicId);
|
||||
$topic = $getTopic->execute() ? $getTopic->fetch() : false;
|
||||
$topic = forum_topic_fetch($topicId);
|
||||
|
||||
if (!$topic) {
|
||||
http_response_code(404);
|
||||
|
@ -50,28 +25,7 @@ if (!$topic) {
|
|||
return;
|
||||
}
|
||||
|
||||
$getPosts = $db->prepare('
|
||||
SELECT
|
||||
p.`post_id`, p.`post_text`, p.`post_created`,
|
||||
p.`topic_id`,
|
||||
u.`user_id` as `poster_id`,
|
||||
u.`username` as `poster_name`,
|
||||
u.`created_at` as `poster_joined`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `poster_colour`
|
||||
FROM `msz_forum_posts` as p
|
||||
LEFT JOIN `msz_users` as u
|
||||
ON u.`user_id` = p.`user_id`
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON r.`role_id` = u.`display_role`
|
||||
WHERE `topic_id` = :topic_id
|
||||
AND `post_deleted` IS NULL
|
||||
ORDER BY `post_id`
|
||||
LIMIT :offset, :take
|
||||
');
|
||||
$getPosts->bindValue('topic_id', $topic['topic_id']);
|
||||
$getPosts->bindValue('offset', $postsOffset);
|
||||
$getPosts->bindValue('take', $postsRange);
|
||||
$posts = $getPosts->execute() ? $getPosts->fetchAll() : [];
|
||||
$posts = forum_post_listing($topic['topic_id'], $postsOffset, $postsRange);
|
||||
|
||||
if (!$posts) {
|
||||
http_response_code(404);
|
||||
|
@ -79,6 +33,8 @@ if (!$posts) {
|
|||
return;
|
||||
}
|
||||
|
||||
forum_topic_mark_read($app->getUserId(), $topic['topic_id'], $topic['forum_id']);
|
||||
|
||||
echo $templating->render('forum.topic', [
|
||||
'topic_breadcrumbs' => forum_get_breadcrumbs($topic['forum_id']),
|
||||
'topic_info' => $topic,
|
||||
|
|
|
@ -10,6 +10,81 @@ define('MSZ_FORUM_TYPES', [
|
|||
MSZ_FORUM_TYPE_LINK,
|
||||
]);
|
||||
|
||||
define('MSZ_FORUM_MAY_HAVE_CHILDREN', [
|
||||
MSZ_FORUM_TYPE_DISCUSSION,
|
||||
MSZ_FORUM_TYPE_CATEGORY,
|
||||
]);
|
||||
|
||||
define('MSZ_FORUM_MAY_HAVE_TOPICS', [
|
||||
MSZ_FORUM_TYPE_DISCUSSION,
|
||||
]);
|
||||
|
||||
define('MSZ_FORUM_ROOT', 0);
|
||||
define('MSZ_FORUM_ROOT_DATA', [ // should be compatible with the data fetched in forum_get_root_categories
|
||||
'forum_id' => 0,
|
||||
'forum_name' => 'Forums',
|
||||
'forum_children' => 0,
|
||||
'forum_type' => MSZ_FORUM_TYPE_CATEGORY,
|
||||
]);
|
||||
|
||||
function forum_may_have_children(int $forumType): bool
|
||||
{
|
||||
return in_array($forumType, MSZ_FORUM_MAY_HAVE_CHILDREN);
|
||||
}
|
||||
|
||||
function forum_may_have_topics(int $forumType): bool
|
||||
{
|
||||
return in_array($forumType, MSZ_FORUM_MAY_HAVE_TOPICS);
|
||||
}
|
||||
|
||||
function forum_fetch(int $forumId): array
|
||||
{
|
||||
$getForum = Database::connection()->prepare('
|
||||
SELECT
|
||||
`forum_id`, `forum_name`, `forum_type`, `forum_link`, `forum_link_clicks`, `forum_parent`,
|
||||
(
|
||||
SELECT COUNT(`topic_id`)
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
) as `forum_topic_count`
|
||||
FROM `msz_forum_categories` as f
|
||||
WHERE `forum_id` = :forum_id
|
||||
');
|
||||
$getForum->bindValue('forum_id', $forumId);
|
||||
|
||||
return $getForum->execute() ? $getForum->fetch() : [];
|
||||
}
|
||||
|
||||
function forum_get_root_categories(): array
|
||||
{
|
||||
$dbc = Database::connection();
|
||||
|
||||
$categories = $dbc->query('
|
||||
SELECT
|
||||
f.`forum_id`, f.`forum_name`, f.`forum_type`,
|
||||
(
|
||||
SELECT COUNT(`forum_id`)
|
||||
FROM `msz_forum_categories` as sf
|
||||
WHERE sf.`forum_parent` = f.`forum_id`
|
||||
) as `forum_children`
|
||||
FROM `msz_forum_categories` as f
|
||||
WHERE f.`forum_parent` = 0
|
||||
AND f.`forum_type` = 1
|
||||
AND f.`forum_hidden` = false
|
||||
ORDER BY f.`forum_order`
|
||||
')->fetchAll();
|
||||
|
||||
$categories = array_merge([MSZ_FORUM_ROOT_DATA], $categories);
|
||||
|
||||
$categories[0]['forum_children'] = (int)$dbc->query('
|
||||
SELECT COUNT(`forum_id`)
|
||||
FROM `msz_forum_categories`
|
||||
WHERE `forum_parent` = ' . MSZ_FORUM_ROOT . '
|
||||
')->fetchColumn();
|
||||
|
||||
return $categories;
|
||||
}
|
||||
|
||||
function forum_get_breadcrumbs(
|
||||
int $forumId,
|
||||
string $linkFormat = '/forum/forum.php?f=%d',
|
||||
|
@ -22,7 +97,7 @@ function forum_get_breadcrumbs(
|
|||
WHERE `forum_id` = :forum_id
|
||||
');
|
||||
|
||||
while ($forumId > 0) {
|
||||
while ($forumId > MSZ_FORUM_ROOT) {
|
||||
$getBreadcrumb->bindValue('forum_id', $forumId);
|
||||
$breadcrumb = $getBreadcrumb->execute() ? $getBreadcrumb->fetch() : [];
|
||||
|
||||
|
@ -43,9 +118,138 @@ function forum_increment_clicks(int $forumId): void
|
|||
UPDATE `msz_forum_categories`
|
||||
SET `forum_link_clicks` = `forum_link_clicks` + 1
|
||||
WHERE `forum_id` = :forum_id
|
||||
AND `forum_type` = 2
|
||||
AND `forum_type` = ' . MSZ_FORUM_TYPE_LINK . '
|
||||
AND `forum_link_clicks` IS NOT NULL
|
||||
');
|
||||
$incrementLinkClicks->bindValue('forum_id', $forumId);
|
||||
$incrementLinkClicks->execute();
|
||||
}
|
||||
|
||||
define('MSZ_FORUM_GET_CHILDREN_QUERY_SMALL', '
|
||||
SELECT
|
||||
:user_id as `target_user_id`,
|
||||
f.`forum_id`, f.`forum_name`,
|
||||
(
|
||||
SELECT
|
||||
`target_user_id` > 0
|
||||
AND
|
||||
t.`topic_id` IS NOT NULL
|
||||
AND
|
||||
t.`topic_bumped` >= NOW() - INTERVAL 1 MONTH
|
||||
AND (
|
||||
SELECT COUNT(ti.`topic_id`) < (
|
||||
SELECT COUNT(`topic_id`)
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
AND `topic_bumped` >= NOW() - INTERVAL 1 MONTH
|
||||
AND `topic_deleted` IS NULL
|
||||
)
|
||||
FROM `msz_forum_topics_track` as tt
|
||||
RIGHT JOIN `msz_forum_topics` as ti
|
||||
ON ti.`topic_id` = tt.`topic_id`
|
||||
WHERE ti.`forum_id` = f.`forum_id`
|
||||
AND tt.`user_id` = `target_user_id`
|
||||
AND `track_last_read` >= `topic_bumped`
|
||||
)
|
||||
) as `forum_unread`
|
||||
FROM `msz_forum_categories` as f
|
||||
LEFT JOIN `msz_forum_topics` as t
|
||||
ON t.`topic_id` = (
|
||||
SELECT `topic_id`
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
AND `topic_deleted` IS NULL
|
||||
ORDER BY `topic_bumped` DESC
|
||||
LIMIT 1
|
||||
)
|
||||
WHERE `forum_parent` = :parent_id
|
||||
AND `forum_hidden` = false
|
||||
ORDER BY f.`forum_order`
|
||||
');
|
||||
define('MSZ_FORUM_GET_CHILDREN_QUERY_STANDARD', '
|
||||
SELECT
|
||||
:user_id as `target_user_id`,
|
||||
f.`forum_id`, f.`forum_name`, f.`forum_description`, f.`forum_type`,
|
||||
f.`forum_link`, f.`forum_link_clicks`, f.`forum_archived`,
|
||||
t.`topic_id` as `recent_topic_id`, p.`post_id` as `recent_post_id`,
|
||||
t.`topic_title` as `recent_topic_title`, t.`topic_bumped` as `recent_topic_bumped`,
|
||||
p.`post_created` as `recent_post_created`,
|
||||
u.`user_id` as `recent_post_user_id`,
|
||||
u.`username` as `recent_post_username`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `recent_post_user_colour`,
|
||||
(
|
||||
SELECT COUNT(`topic_id`)
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
) as `forum_topic_count`,
|
||||
(
|
||||
SELECT COUNT(`post_id`)
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
) as `forum_post_count`,
|
||||
(
|
||||
SELECT
|
||||
`target_user_id` > 0
|
||||
AND
|
||||
`recent_topic_id` IS NOT NULL
|
||||
AND
|
||||
`recent_topic_bumped` >= NOW() - INTERVAL 1 MONTH
|
||||
AND (
|
||||
SELECT COUNT(ti.`topic_id`) < (
|
||||
SELECT COUNT(`topic_id`)
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
AND `topic_bumped` >= NOW() - INTERVAL 1 MONTH
|
||||
AND `topic_deleted` IS NULL
|
||||
)
|
||||
FROM `msz_forum_topics_track` as tt
|
||||
RIGHT JOIN `msz_forum_topics` as ti
|
||||
ON ti.`topic_id` = tt.`topic_id`
|
||||
WHERE ti.`forum_id` = f.`forum_id`
|
||||
AND tt.`user_id` = `target_user_id`
|
||||
AND `track_last_read` >= `topic_bumped`
|
||||
)
|
||||
) as `forum_unread`
|
||||
FROM `msz_forum_categories` as f
|
||||
LEFT JOIN `msz_forum_topics` as t
|
||||
ON t.`topic_id` = (
|
||||
SELECT `topic_id`
|
||||
FROM `msz_forum_topics`
|
||||
WHERE `forum_id` = f.`forum_id`
|
||||
AND `topic_deleted` IS NULL
|
||||
ORDER BY `topic_bumped` DESC
|
||||
LIMIT 1
|
||||
)
|
||||
LEFT JOIN `msz_forum_posts` as p
|
||||
ON p.`post_id` = (
|
||||
SELECT `post_id`
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
ORDER BY `post_id` DESC
|
||||
LIMIT 1
|
||||
)
|
||||
LEFT JOIN `msz_users` as u
|
||||
ON u.`user_id` = p.`user_id`
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON r.`role_id` = u.`display_role`
|
||||
WHERE f.`forum_parent` = :parent_id
|
||||
AND f.`forum_hidden` = false
|
||||
AND (
|
||||
(f.`forum_parent` = ' . MSZ_FORUM_ROOT . ' AND f.`forum_type` != ' . MSZ_FORUM_TYPE_CATEGORY . ')
|
||||
OR f.`forum_parent` != ' . MSZ_FORUM_ROOT . '
|
||||
)
|
||||
ORDER BY f.`forum_order`
|
||||
');
|
||||
|
||||
function forum_get_children(int $parentId, int $userId, bool $small = false): array
|
||||
{
|
||||
$getListing = Database::connection()->prepare(
|
||||
$small
|
||||
? MSZ_FORUM_GET_CHILDREN_QUERY_SMALL
|
||||
: MSZ_FORUM_GET_CHILDREN_QUERY_STANDARD
|
||||
);
|
||||
$getListing->bindValue('user_id', $userId);
|
||||
$getListing->bindValue('parent_id', $parentId);
|
||||
|
||||
return $getListing->execute() ? $getListing->fetchAll() : [];
|
||||
}
|
||||
|
|
|
@ -47,3 +47,40 @@ function forum_post_find(int $postId): array
|
|||
|
||||
return $getPostInfo->execute() ? $getPostInfo->fetch() : false;
|
||||
}
|
||||
|
||||
define('MSZ_FORUM_POST_LISTING_QUERY_STANDARD', '
|
||||
SELECT
|
||||
p.`post_id`, p.`post_text`, p.`post_created`,
|
||||
p.`topic_id`,
|
||||
u.`user_id` as `poster_id`,
|
||||
u.`username` as `poster_name`,
|
||||
u.`created_at` as `poster_joined`,
|
||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `poster_colour`
|
||||
FROM `msz_forum_posts` as p
|
||||
LEFT JOIN `msz_users` as u
|
||||
ON u.`user_id` = p.`user_id`
|
||||
LEFT JOIN `msz_roles` as r
|
||||
ON r.`role_id` = u.`display_role`
|
||||
WHERE `topic_id` = :topic_id
|
||||
AND `post_deleted` IS NULL
|
||||
ORDER BY `post_id`
|
||||
');
|
||||
define('MSZ_FORUM_POST_LISTING_QUERY_PAGINATED', MSZ_FORUM_POST_LISTING_QUERY_STANDARD . ' LIMIT :offset, :take');
|
||||
|
||||
function forum_post_listing(int $topicId, int $offset = 0, int $take = 0): array
|
||||
{
|
||||
$hasPagination = $offset >= 0 && $take > 0;
|
||||
$getPosts = Database::connection()->prepare(
|
||||
$hasPagination
|
||||
? MSZ_FORUM_POST_LISTING_QUERY_PAGINATED
|
||||
: MSZ_FORUM_POST_LISTING_QUERY_STANDARD
|
||||
);
|
||||
$getPosts->bindValue('topic_id', $topicId);
|
||||
|
||||
if ($hasPagination) {
|
||||
$getPosts->bindValue('offset', $offset);
|
||||
$getPosts->bindValue('take', $take);
|
||||
}
|
||||
|
||||
return $getPosts->execute() ? $getPosts->fetchAll() : [];
|
||||
}
|
||||
|
|
|
@ -27,6 +27,33 @@ function forum_topic_create(int $forumId, int $userId, string $title): int
|
|||
return $createTopic->execute() ? (int)$dbc->lastInsertId() : 0;
|
||||
}
|
||||
|
||||
function forum_topic_fetch(int $topicId): array
|
||||
{
|
||||
$getTopic = Database::connection()->prepare('
|
||||
SELECT
|
||||
t.`topic_id`, t.`forum_id`, t.`topic_title`, t.`topic_type`, t.`topic_locked`,
|
||||
f.`forum_archived` as `topic_archived`,
|
||||
(
|
||||
SELECT MIN(`post_id`)
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
) as `topic_first_post_id`,
|
||||
(
|
||||
SELECT COUNT(`post_id`)
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
) as `topic_post_count`
|
||||
FROM `msz_forum_topics` as t
|
||||
LEFT JOIN `msz_forum_categories` as f
|
||||
ON f.`forum_id` = t.`forum_id`
|
||||
WHERE t.`topic_id` = :topic_id
|
||||
AND t.`topic_deleted` IS NULL
|
||||
');
|
||||
$getTopic->bindValue('topic_id', $topicId);
|
||||
|
||||
return $getTopic->execute() ? $getTopic->fetch() : [];
|
||||
}
|
||||
|
||||
function forum_topic_bump(int $topicId): bool
|
||||
{
|
||||
$bumpTopic = Database::connection()->prepare('
|
||||
|
@ -37,3 +64,99 @@ function forum_topic_bump(int $topicId): bool
|
|||
$bumpTopic->bindValue('topic_id', $topicId);
|
||||
return $bumpTopic->execute();
|
||||
}
|
||||
|
||||
function forum_topic_mark_read(int $userId, int $topicId, int $forumId): void
|
||||
{
|
||||
if ($userId < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$markAsRead = Database::connection()->prepare('
|
||||
REPLACE INTO `msz_forum_topics_track`
|
||||
(`user_id`, `topic_id`, `forum_id`, `track_last_read`)
|
||||
VALUES
|
||||
(:user_id, :topic_id, :forum_id, NOW())
|
||||
');
|
||||
$markAsRead->bindValue('user_id', $userId);
|
||||
$markAsRead->bindValue('topic_id', $topicId);
|
||||
$markAsRead->bindValue('forum_id', $forumId);
|
||||
$markAsRead->execute();
|
||||
}
|
||||
|
||||
define('MSZ_TOPIC_LISTING_QUERY_STANDARD', '
|
||||
SELECT
|
||||
:user_id as `target_user_id`,
|
||||
t.`topic_id`, t.`topic_title`, t.`topic_locked`, t.`topic_type`, t.`topic_created`,
|
||||
au.`user_id` as `author_id`, au.`username` as `author_name`,
|
||||
COALESCE(ar.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `author_colour`,
|
||||
lp.`post_id` as `response_id`,
|
||||
lp.`post_created` as `response_created`,
|
||||
lu.`user_id` as `respondent_id`,
|
||||
lu.`username` as `respondent_name`,
|
||||
COALESCE(lr.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `respondent_colour`,
|
||||
(
|
||||
SELECT COUNT(`post_id`)
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
) as `topic_post_count`,
|
||||
(
|
||||
SELECT COUNT(`user_id`)
|
||||
FROM `msz_forum_topics_track`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
) as `topic_view_count`,
|
||||
(
|
||||
SELECT
|
||||
`target_user_id` > 0
|
||||
AND
|
||||
t.`topic_bumped` > NOW() - INTERVAL 1 MONTH
|
||||
AND (
|
||||
SELECT COUNT(ti.`topic_id`) < 1
|
||||
FROM `msz_forum_topics_track` as tt
|
||||
RIGHT JOIN `msz_forum_topics` as ti
|
||||
ON ti.`topic_id` = tt.`topic_id`
|
||||
WHERE ti.`topic_id` = t.`topic_id`
|
||||
AND tt.`user_id` = `target_user_id`
|
||||
AND `track_last_read` >= `topic_bumped`
|
||||
)
|
||||
) as `topic_unread`
|
||||
FROM `msz_forum_topics` as t
|
||||
LEFT JOIN `msz_users` as au
|
||||
ON t.`user_id` = au.`user_id`
|
||||
LEFT JOIN `msz_roles` as ar
|
||||
ON ar.`role_id` = au.`display_role`
|
||||
LEFT JOIN `msz_forum_posts` as lp
|
||||
ON lp.`post_id` = (
|
||||
SELECT `post_id`
|
||||
FROM `msz_forum_posts`
|
||||
WHERE `topic_id` = t.`topic_id`
|
||||
ORDER BY `post_id` DESC
|
||||
LIMIT 1
|
||||
)
|
||||
LEFT JOIN `msz_users` as lu
|
||||
ON lu.`user_id` = lp.`user_id`
|
||||
LEFT JOIN `msz_roles` as lr
|
||||
ON lr.`role_id` = lu.`display_role`
|
||||
WHERE t.`forum_id` = :forum_id
|
||||
AND t.`topic_deleted` IS NULL
|
||||
ORDER BY t.`topic_type` DESC, t.`topic_bumped` DESC
|
||||
');
|
||||
define('MSZ_TOPIC_LISTING_QUERY_PAGINATED', MSZ_TOPIC_LISTING_QUERY_STANDARD . ' LIMIT :offset, :take');
|
||||
|
||||
function forum_topic_listing(int $forumId, int $userId, int $offset = 0, int $take = 0): array
|
||||
{
|
||||
$hasPagination = $offset >= 0 && $take > 0;
|
||||
$getTopics = Database::connection()->prepare(
|
||||
$hasPagination
|
||||
? MSZ_TOPIC_LISTING_QUERY_PAGINATED
|
||||
: MSZ_TOPIC_LISTING_QUERY_STANDARD
|
||||
);
|
||||
$getTopics->bindValue('forum_id', $forumId);
|
||||
$getTopics->bindValue('user_id', $userId);
|
||||
|
||||
if ($hasPagination) {
|
||||
$getTopics->bindValue('offset', $offset);
|
||||
$getTopics->bindValue('take', $take);
|
||||
}
|
||||
|
||||
return $getTopics->execute() ? $getTopics->fetchAll() : [];
|
||||
}
|
||||
|
|
|
@ -23,9 +23,9 @@
|
|||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro forum_category_entry(forum, forum_type, forum_read, forum_icon) %}
|
||||
{% macro forum_category_entry(forum, forum_unread, forum_type, forum_icon) %}
|
||||
{% set forum_type = forum_type|default(null) %}
|
||||
{% set forum_read = forum_read|default(true) ? 'read' : 'unread' %}
|
||||
{% set forum_unread = forum_unread|default(forum.forum_unread|default(false)) ? 'unread' : 'read' %}
|
||||
{% set forum_icon = forum_icon|default('https://static.flash.moe/images/forum-icons/forum-%s-%s.png') %}
|
||||
|
||||
{% if forum_type is null %}
|
||||
|
@ -43,7 +43,7 @@
|
|||
{% endif %}
|
||||
|
||||
<div class="forum__listing__entry">
|
||||
<img src="{{ forum_icon|format(forum_type, forum_read) }}" alt="read" class="forum__listing__entry__icon">
|
||||
<img src="{{ forum_icon|format(forum_type, forum_unread) }}" alt="{{ forum_unread }}" class="forum__listing__entry__icon">
|
||||
|
||||
<div class="forum__listing__entry__info">
|
||||
<div class="forum__listing__entry__title">
|
||||
|
@ -57,7 +57,10 @@
|
|||
{% if forum.forum_subforums is defined and forum.forum_subforums|length > 0 %}
|
||||
<div class="forum__listing__entry__subforums">
|
||||
{% for subforum in forum.forum_subforums %}
|
||||
<a href="/forum/forum.php?f={{ subforum.forum_id }}" class="forum__listing__entry__subforum">{{ subforum.forum_name }}</a>
|
||||
<a href="/forum/forum.php?f={{ subforum.forum_id }}"
|
||||
class="forum__listing__entry__subforum{% if subforum.forum_unread %} forum__listing__entry__subforum--unread{% endif %}">
|
||||
{{ subforum.forum_name }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -158,9 +161,9 @@
|
|||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro forum_topic_entry(topic, topic_type, topic_read, topic_icon) %}
|
||||
{% macro forum_topic_entry(topic, topic_type, topic_unread, topic_icon) %}
|
||||
{% set topic_type = topic_type|default(null) %}
|
||||
{% set topic_read = topic_read|default(true) ? 'read' : 'unread' %}
|
||||
{% set topic_unread = topic_unread|default(topic.topic_unread|default(false)) ? 'unread' : 'read' %}
|
||||
{% set topic_icon = topic_icon|default('https://static.flash.moe/images/topic-icons/topic-%s-%s.png') %}
|
||||
|
||||
{% if topic_type is null %}
|
||||
|
@ -180,10 +183,10 @@
|
|||
{% endif %}
|
||||
|
||||
<div class="forum__topics__entry forum__topics__entry--{{ topic_type }}">
|
||||
<img src="{{ topic_icon|format(topic_type, topic_read) }}" alt="read" class="forum__topics__entry__icon">
|
||||
<img src="{{ topic_icon|format(topic_type, topic_unread) }}" alt="{{ topic_unread }}" class="forum__topics__entry__icon">
|
||||
|
||||
<div class="forum__topics__entry__info">
|
||||
<div class="forum__topics__entry__info__title forum__topics__entry__info__title--{{ topic_read }}">
|
||||
<div class="forum__topics__entry__info__title forum__topics__entry__info__title--{{ topic_unread }}">
|
||||
<a href="/forum/topic.php?t={{ topic.topic_id }}" class="forum__topics__entry__info__title__link">{{ topic.topic_title }}</a>
|
||||
</div>
|
||||
<div class="forum__topics__entry__info__author">
|
||||
|
|
Loading…
Add table
Reference in a new issue