unfinished forum stuff
This commit is contained in:
parent
e59ea5dfb7
commit
387ab2ccb4
19 changed files with 573 additions and 20 deletions
|
@ -5,6 +5,10 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__none {
|
||||||
|
padding: 2px 5px;
|
||||||
|
}
|
||||||
|
|
||||||
&__entry {
|
&__entry {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 2px 0;
|
padding: 2px 0;
|
||||||
|
@ -16,8 +20,6 @@
|
||||||
|
|
||||||
&__icon {
|
&__icon {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
line-height: 50px;
|
|
||||||
font-size: 2.5em;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
@ -26,6 +28,7 @@
|
||||||
&__info {
|
&__info {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
|
padding-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
|
|
3
assets/less/mio/classes/forum/topics.less
Normal file
3
assets/less/mio/classes/forum/topics.less
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.forum__topics {
|
||||||
|
//
|
||||||
|
}
|
|
@ -17,6 +17,16 @@
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&--left {
|
||||||
|
justify-content: left;
|
||||||
|
padding-left: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--right {
|
||||||
|
justify-content: right;
|
||||||
|
padding-right: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
&--top {
|
&--top {
|
||||||
border-top-width: 0;
|
border-top-width: 0;
|
||||||
border-bottom-width: 1px;
|
border-bottom-width: 1px;
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
namespace Misuzu\DatabaseMigrations\InitialStructure;
|
namespace Misuzu\DatabaseMigrations\InitialStructure;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
use Misuzu\Database;
|
|
||||||
|
|
||||||
function migrate_up(PDO $conn): void
|
function migrate_up(PDO $conn): void
|
||||||
{
|
{
|
||||||
|
|
135
database/2018_05_17_000055_forum_structure.php
Normal file
135
database/2018_05_17_000055_forum_structure.php
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\DatabaseMigrations\ForumStructure;
|
||||||
|
|
||||||
|
use PDO;
|
||||||
|
|
||||||
|
function migrate_up(PDO $conn): void
|
||||||
|
{
|
||||||
|
$conn->exec("
|
||||||
|
CREATE TABLE `msz_forum_categories` (
|
||||||
|
`forum_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`forum_order` INT(10) UNSIGNED NOT NULL DEFAULT '1',
|
||||||
|
`forum_parent` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`forum_name` VARCHAR(255) NOT NULL,
|
||||||
|
`forum_type` TINYINT(4) NOT NULL DEFAULT '0',
|
||||||
|
`forum_description` TEXT NULL,
|
||||||
|
`forum_link` VARCHAR(255) NULL DEFAULT NULL,
|
||||||
|
`forum_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`forum_archived` TINYINT(1) NOT NULL DEFAULT '0',
|
||||||
|
`forum_hidden` TINYINT(1) NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`forum_id`),
|
||||||
|
INDEX `forums_indices` (`forum_order`, `forum_parent`, `forum_type`)
|
||||||
|
)
|
||||||
|
");
|
||||||
|
|
||||||
|
$conn->exec("
|
||||||
|
CREATE TABLE `msz_forum_topics` (
|
||||||
|
`topic_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`forum_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
|
||||||
|
`topic_title` VARCHAR(255) NOT NULL,
|
||||||
|
`topic_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`topic_bumped` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`topic_deleted` TIMESTAMP NULL DEFAULT NULL,
|
||||||
|
`topic_view_count` INT(10) NOT NULL DEFAULT '0',
|
||||||
|
`topic_type` TINYINT(4) NOT NULL DEFAULT '0',
|
||||||
|
`topic_status` TINYINT(4) NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`topic_id`),
|
||||||
|
INDEX `topics_forum_id_foreign` (`forum_id`),
|
||||||
|
INDEX `topics_user_id_foreign` (`user_id`),
|
||||||
|
INDEX `topics_indices` (`topic_bumped`, `topic_type`),
|
||||||
|
CONSTRAINT `topics_forum_id_foreign`
|
||||||
|
FOREIGN KEY (`forum_id`)
|
||||||
|
REFERENCES `msz_forum_categories` (`forum_id`)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE CASCADE,
|
||||||
|
CONSTRAINT `topics_user_id_foreign`
|
||||||
|
FOREIGN KEY (`user_id`)
|
||||||
|
REFERENCES `msz_users` (`user_id`)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE CASCADE
|
||||||
|
)
|
||||||
|
");
|
||||||
|
|
||||||
|
$conn->exec("
|
||||||
|
CREATE TABLE `msz_forum_posts` (
|
||||||
|
`post_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`topic_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`forum_id` INT(10) UNSIGNED NOT NULL,
|
||||||
|
`user_id` INT(10) UNSIGNED NULL DEFAULT NULL,
|
||||||
|
`post_title` VARCHAR(255) NOT NULL,
|
||||||
|
`post_ip` BLOB NOT NULL,
|
||||||
|
`post_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`post_edited` TIMESTAMP NULL DEFAULT NULL,
|
||||||
|
`post_deleted` TIMESTAMP NULL DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`post_id`),
|
||||||
|
INDEX `posts_topic_id_foreign` (`topic_id`),
|
||||||
|
INDEX `posts_forum_id_foreign` (`forum_id`),
|
||||||
|
INDEX `posts_user_id_foreign` (`user_id`),
|
||||||
|
INDEX `posts_indices` (`post_created`),
|
||||||
|
CONSTRAINT `posts_topic_id_foreign`
|
||||||
|
FOREIGN KEY (`topic_id`)
|
||||||
|
REFERENCES `msz_forum_topics` (`topic_id`)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE CASCADE,
|
||||||
|
CONSTRAINT `posts_forum_id_foreign`
|
||||||
|
FOREIGN KEY (`forum_id`)
|
||||||
|
REFERENCES `msz_forum_categories` (`forum_id`)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE CASCADE,
|
||||||
|
CONSTRAINT `posts_user_id_foreign`
|
||||||
|
FOREIGN KEY (`user_id`)
|
||||||
|
REFERENCES `msz_users` (`user_id`)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE SET NULL
|
||||||
|
)
|
||||||
|
");
|
||||||
|
|
||||||
|
$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,
|
||||||
|
`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`),
|
||||||
|
CONSTRAINT `topics_track_topic_id_foreign`
|
||||||
|
FOREIGN KEY (`topic_id`)
|
||||||
|
REFERENCES `msz_forum_topics` (`topic_id`)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE CASCADE,
|
||||||
|
CONSTRAINT `topics_track_user_id_foreign`
|
||||||
|
FOREIGN KEY (`user_id`)
|
||||||
|
REFERENCES `msz_users` (`user_id`)
|
||||||
|
ON UPDATE CASCADE
|
||||||
|
ON DELETE CASCADE
|
||||||
|
)
|
||||||
|
");
|
||||||
|
}
|
||||||
|
|
||||||
|
function migrate_down(PDO $conn): void
|
||||||
|
{
|
||||||
|
$conn->exec('DROP TABLE `msz_forum_topics_track`');
|
||||||
|
$conn->exec('DROP TABLE `msz_forum_posts`');
|
||||||
|
$conn->exec('DROP TABLE `msz_forum_topics`');
|
||||||
|
$conn->exec('DROP TABLE `msz_forum_categories`');
|
||||||
|
}
|
130
public/forum/forum.php
Normal file
130
public/forum/forum.php
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
<?php
|
||||||
|
use Misuzu\Database;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../../misuzu.php';
|
||||||
|
|
||||||
|
$forumId = (int)($_GET['f'] ?? 0);
|
||||||
|
|
||||||
|
if ($forumId === 0) {
|
||||||
|
header('Location: /forum/');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$db = Database::connection();
|
||||||
|
$templating = $app->getTemplating();
|
||||||
|
|
||||||
|
if ($forumId > 0) {
|
||||||
|
$getForum = $db->prepare('
|
||||||
|
SELECT
|
||||||
|
`forum_id`, `forum_name`, `forum_type`, `forum_link`, `forum_parent`
|
||||||
|
FROM `msz_forum_categories`
|
||||||
|
WHERE `forum_id` = :forum_id
|
||||||
|
');
|
||||||
|
$getForum->bindValue('forum_id', $forumId);
|
||||||
|
$forum = $getForum->execute() ? $getForum->fetch() : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($forum) || ($forum['forum_type'] == 2 && empty($forum['forum_link']))) {
|
||||||
|
http_response_code(404);
|
||||||
|
echo $templating->render('errors.404');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($forum['forum_type'] == 2) {
|
||||||
|
header('Location: ' . $forum['forum_link']);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// declare this, templating engine assumes it exists
|
||||||
|
$topics = [];
|
||||||
|
|
||||||
|
// no need to fetch topics for categories (or links but we're already done with those at this point)
|
||||||
|
if ($forum['forum_type'] == 0) {
|
||||||
|
$getTopics = $db->prepare('
|
||||||
|
SELECT
|
||||||
|
t.`topic_id`, t.`topic_title`, t.`topic_view_count`,
|
||||||
|
au.`user_id` as `author_id`, au.`username` as `author_name`,
|
||||||
|
COUNT(p.`post_id`) as `topic_post_count`,
|
||||||
|
MIN(p.`post_id`) as `topic_first_post_id`,
|
||||||
|
MAX(p.`post_id`) as `topic_last_post_id`,
|
||||||
|
COALESCE(ar.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `author_colour`
|
||||||
|
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 p
|
||||||
|
ON t.`topic_id` = p.`topic_id`
|
||||||
|
WHERE t.`forum_id` = :forum_id
|
||||||
|
AND t.`topic_deleted` IS NULL
|
||||||
|
GROUP BY t.`topic_id`
|
||||||
|
ORDER BY t.`topic_type`, t.`topic_bumped`
|
||||||
|
');
|
||||||
|
$getTopics->bindValue('forum_id', $forum['forum_id']);
|
||||||
|
$topics = $getTopics->execute() ? $getTopics->fetchAll() : $topics;
|
||||||
|
}
|
||||||
|
|
||||||
|
$getSubforums = $db->prepare('
|
||||||
|
SELECT
|
||||||
|
`forum_id`, `forum_name`, `forum_description`, `forum_type`, `forum_link`,
|
||||||
|
(
|
||||||
|
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
|
||||||
|
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() : [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$lastParent = $forum['forum_parent'];
|
||||||
|
$breadcrumbs = [$forum['forum_name'] => '/forum/forum.php?f=' . $forum['forum_id']];
|
||||||
|
$getBreadcrumb = $db->prepare('
|
||||||
|
SELECT `forum_id`, `forum_name`, `forum_parent`
|
||||||
|
FROM `msz_forum_categories`
|
||||||
|
WHERE `forum_id` = :forum_id
|
||||||
|
');
|
||||||
|
|
||||||
|
while ($lastParent > 0) {
|
||||||
|
$getBreadcrumb->bindValue('forum_id', $lastParent);
|
||||||
|
|
||||||
|
if (!$getBreadcrumb->execute()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parentForum = $getBreadcrumb->fetch();
|
||||||
|
|
||||||
|
$breadcrumbs[$parentForum['forum_name']] = '/forum/forum.php?f=' . $parentForum['forum_id'];
|
||||||
|
$lastParent = $parentForum['forum_parent'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$breadcrumbs['Forums'] = '/forum/';
|
||||||
|
$breadcrumbs = array_reverse($breadcrumbs);
|
||||||
|
|
||||||
|
echo $app->getTemplating()->render('forum.forum', [
|
||||||
|
'forum_info' => $forum,
|
||||||
|
'forum_breadcrumbs' => $breadcrumbs,
|
||||||
|
'forum_topics' => $topics,
|
||||||
|
]);
|
73
public/forum/index.php
Normal file
73
public/forum/index.php
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
use Misuzu\Database;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../../misuzu.php';
|
||||||
|
|
||||||
|
$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
|
||||||
|
GROUP BY f.`forum_id`
|
||||||
|
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`,
|
||||||
|
(
|
||||||
|
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
|
||||||
|
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`
|
||||||
|
');
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$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']);
|
||||||
|
$categories[$key]['forum_subforums'][$skey]['forum_subforums']
|
||||||
|
= $getSubCategories->execute() ? $getSubCategories->fetchAll() : [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$categories[0]['forum_children'] = count($categories[0]['forum_subforums']);
|
||||||
|
|
||||||
|
echo $app->getTemplating()->render('forum.index', [
|
||||||
|
'forum_categories' => $categories,
|
||||||
|
]);
|
6
public/forum/topic.php
Normal file
6
public/forum/topic.php
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
use Misuzu\Database;
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../../misuzu.php';
|
||||||
|
|
||||||
|
echo $app->getTemplating()->render('forum.topic');
|
|
@ -1,6 +1,5 @@
|
||||||
<?php
|
<?php
|
||||||
use Misuzu\Database;
|
use Misuzu\Database;
|
||||||
use Misuzu\DatabaseMigrationManager;
|
|
||||||
|
|
||||||
require_once __DIR__ . '/../misuzu.php';
|
require_once __DIR__ . '/../misuzu.php';
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,17 @@ switch ($mode) {
|
||||||
SELECT
|
SELECT
|
||||||
u.*,
|
u.*,
|
||||||
r.`role_title` as `user_title`,
|
r.`role_title` as `user_title`,
|
||||||
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `display_colour`
|
COALESCE(r.`role_colour`, CAST(0x40000000 AS UNSIGNED)) as `display_colour`,
|
||||||
|
(
|
||||||
|
SELECT COUNT(`topic_id`)
|
||||||
|
FROM `msz_forum_topics` as t
|
||||||
|
WHERE t.`user_id` = u.`user_id`
|
||||||
|
) as `forum_topic_count`,
|
||||||
|
(
|
||||||
|
SELECT COUNT(`post_id`)
|
||||||
|
FROM `msz_forum_posts` as p
|
||||||
|
WHERE p.`user_id` = u.`user_id`
|
||||||
|
) as `forum_post_count`
|
||||||
FROM `msz_users` as u
|
FROM `msz_users` as u
|
||||||
LEFT JOIN `msz_roles` as r
|
LEFT JOIN `msz_roles` as r
|
||||||
ON r.`role_id` = u.`display_role`
|
ON r.`role_id` = u.`display_role`
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<a href="?m=create" class="button">Create new Role</a>
|
<a href="?v=role" class="button">Create new Role</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container listing role-listing">
|
<div class="container listing role-listing">
|
||||||
|
|
20
views/mio/forum/forum.twig
Normal file
20
views/mio/forum/forum.twig
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{% extends '@mio/forum/master.twig' %}
|
||||||
|
{% from '@mio/macros.twig' import navigation %}
|
||||||
|
{% from '@mio/forum/macros.twig' import forum_category_listing, forum_topic_listing %}
|
||||||
|
|
||||||
|
{% set title = forum_info.forum_name %}
|
||||||
|
{% set canonical_url = '/forum/forum.php?f=' ~ forum_info.forum_id %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{{ navigation(forum_breadcrumbs, forum_breadcrumbs|last, true, null, 'left') }}
|
||||||
|
|
||||||
|
{% if forum_info.forum_subforums|length > 0 or forum_info.forum_type == 1 %}
|
||||||
|
{{ forum_category_listing(forum_info.forum_subforums, 'Forums') }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if forum_info.forum_type == 0 %}
|
||||||
|
{{ forum_topic_listing(forum_topics) }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{{ navigation(mio_navigation, '/forum/') }}
|
||||||
|
{% endblock %}
|
27
views/mio/forum/index.twig
Normal file
27
views/mio/forum/index.twig
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{% extends '@mio/forum/master.twig' %}
|
||||||
|
{% from '@mio/macros.twig' import navigation %}
|
||||||
|
{% from '@mio/forum/macros.twig' import forum_category_listing %}
|
||||||
|
|
||||||
|
{% set title = 'Forum Listing' %}
|
||||||
|
{% set canonical_url = '/forum/' %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% for category in forum_categories %}
|
||||||
|
{% if category.forum_children > 0 %}
|
||||||
|
{{ forum_category_listing(category.forum_subforums, category.forum_name) }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="container__title">Actions</div>
|
||||||
|
<div class="container__content">
|
||||||
|
<button class="input__button">Mark All Read</button>
|
||||||
|
<button class="input__button">Unanswered Posts</button>
|
||||||
|
<button class="input__button">New Posts</button>
|
||||||
|
<button class="input__button">Your Posts</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ navigation(mio_navigation, '/forum/') }}
|
||||||
|
{% endblock %}
|
||||||
|
|
115
views/mio/forum/macros.twig
Normal file
115
views/mio/forum/macros.twig
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
{% macro forum_category_listing(forums, title) %}
|
||||||
|
{% from _self import forum_category_entry %}
|
||||||
|
|
||||||
|
<div class="container forum__listing">
|
||||||
|
<div class="container__title">{{ title }}</div>
|
||||||
|
<div class="container__content forum__listing__forums">
|
||||||
|
{% if forums|length > 0 %}
|
||||||
|
{% for forum in forums %}
|
||||||
|
{{ forum_category_entry(forum) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<div class="forum__listing__none">
|
||||||
|
This category is empty.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro forum_category_entry(forum, forum_icon) %}
|
||||||
|
{% set forum_icon = forum_icon|default(null) %}
|
||||||
|
|
||||||
|
{% if forum_icon is null %}
|
||||||
|
{% if forum.forum_archived is defined and forum.forum_archived %}
|
||||||
|
{% set forum_icon = 'https://static.flash.moe/images/forum-icons/default-archived-%s.png' %}
|
||||||
|
{% elseif forum.forum_type is defined %}
|
||||||
|
{% if forum.forum_type == 2 %}
|
||||||
|
{% set forum_icon = 'https://static.flash.moe/images/forum-icons/default-link-%s.png' %}
|
||||||
|
{% elseif forum.forum_type == 1 %}
|
||||||
|
{% set forum_icon = 'https://static.flash.moe/images/forum-icons/default-category-%s.png' %}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% set forum_icon = forum_icon|default('https://static.flash.moe/images/forum-icons/default-forum-%s.png') %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="forum__listing__entry">
|
||||||
|
<div class="forum__listing__entry__icon">
|
||||||
|
<img src="{{ forum_icon|format('read') }}" alt="read">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="forum__listing__entry__info">
|
||||||
|
<a href="/forum/forum.php?f={{ forum.forum_id }}" class="forum__listing__entry__title">{{ forum.forum_name }}</a>
|
||||||
|
<div class="forum__listing__entry__description">
|
||||||
|
{{ forum.forum_description|nl2br }}
|
||||||
|
{% if forum.forum_subforums is defined and forum.forum_subforums|length > 0 %}
|
||||||
|
<br>
|
||||||
|
{% set listing = [] %}
|
||||||
|
{% for subforum in forum.forum_subforums %}
|
||||||
|
{% set listing = listing|merge(['<a href="/forum/forum.php?f='|raw ~ subforum.forum_id ~ '">'|raw ~ subforum.forum_name ~ '</a>'|raw]) %}
|
||||||
|
{% endfor %}
|
||||||
|
{{ listing|join(', ')|raw }}
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="forum__listing__entry__stats">
|
||||||
|
<div class="forum__listing__entry__topics">{{ forum.forum_topic_count|number_format }}</div>
|
||||||
|
<div class="forum__listing__entry__posts">{{ forum.forum_post_count|number_format }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="forum__listing__entry__activity">
|
||||||
|
<div class="forum__listing__entry__activity__none">
|
||||||
|
There are no posts in this forum yet.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro forum_topic_listing(topics) %}
|
||||||
|
{% from _self import forum_topic_entry %}
|
||||||
|
|
||||||
|
<div class="container forum__topics">
|
||||||
|
<div class="container__title">Topics</div>
|
||||||
|
<div class="container__content forum__topics__listing">
|
||||||
|
{% if topics|length > 0 %}
|
||||||
|
{% for topic in topics %}
|
||||||
|
{{ forum_topic_entry(topic) }}
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<div class="forum__topics__none">
|
||||||
|
There are no topics in this forum.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro forum_topic_entry(topic) %}
|
||||||
|
<div class="forum__topics__entry">
|
||||||
|
<div class="forum__topics__icon">
|
||||||
|
eek
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="forum__topics__info">
|
||||||
|
<div class="forum__topics__info__title">
|
||||||
|
<a href="/forum/topic.php?t={{ topic.topic_id }}">{{ topic.topic_title }}</a>
|
||||||
|
</div>
|
||||||
|
{% if topic.author_id is not null %}
|
||||||
|
<div class="forum__topics__info__author">
|
||||||
|
by <a href="/profile.php?u={{ topic.author_id }}" style="color:{{ topic.author_colour|colour_get_css }}">{{ topic.author_name }}</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="forum__topics__stats">
|
||||||
|
<div class="forum__topics__stat forum__topics__stat--posts">{{ topic.topic_post_count }}</div>
|
||||||
|
<div class="forum__topics__stat forum__topics__stat--views">{{ topic.topic_view_count }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="forum__topics__last-reply">
|
||||||
|
last post data required here, display "no replies" when only one post is present
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
1
views/mio/forum/master.twig
Normal file
1
views/mio/forum/master.twig
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{% extends '@mio/master.twig' %}
|
0
views/mio/forum/topic.twig
Normal file
0
views/mio/forum/topic.twig
Normal file
|
@ -4,12 +4,13 @@
|
||||||
{% endspaceless %}
|
{% endspaceless %}
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
{% macro navigation(links, current, top, fmt) %}
|
{% macro navigation(links, current, top, fmt, align) %}
|
||||||
{% set top = top|default(false) == true %}
|
{% set top = top|default(false) == true %}
|
||||||
|
{% set align = align|default('centre') %}
|
||||||
{% set current = current|default(null) %}
|
{% set current = current|default(null) %}
|
||||||
{% set fmt = fmt|default('%s') %}
|
{% set fmt = fmt|default('%s') %}
|
||||||
|
|
||||||
<ul class="navigation{% if top %} navigation--top{% endif %}">
|
<ul class="navigation{% if top %} navigation--top{% endif %}{% if align != 'centre' %} navigation--{{ align }}{% endif %}">
|
||||||
{% for name, url in links %}
|
{% for name, url in links %}
|
||||||
<li class="navigation__option{% if url == current or name == current %} navigation__option--selected{% endif %}"><a href="{{ fmt|format(url) }}" class="navigation__link">{{ name }}</a></li>
|
<li class="navigation__option{% if url == current or name == current %} navigation__option--selected{% endif %}"><a href="{{ fmt|format(url) }}" class="navigation__link">{{ name }}</a></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
{% set mio_navigation = {
|
{% set mio_navigation = {
|
||||||
'Home': '/',
|
'Home': '/',
|
||||||
'News': '/news.php',
|
'News': '/news.php',
|
||||||
|
'Forum': '/forum/',
|
||||||
'Chat': 'https://chat.flashii.net',
|
'Chat': 'https://chat.flashii.net',
|
||||||
} %}
|
} %}
|
||||||
|
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{# if profile.last_seen.timestamp > 0 #}
|
{% if profile.last_seen is not null %}
|
||||||
<div class="profile__info__row" title="{{ profile.last_seen }}">
|
<div class="profile__info__row" title="{{ profile.last_seen }}">
|
||||||
<div class="profile__info__column profile__info__column--heading">
|
<div class="profile__info__column profile__info__column--heading">
|
||||||
Last Seen
|
Last Seen
|
||||||
|
@ -114,7 +114,27 @@
|
||||||
{{ profile.last_seen }}
|
{{ profile.last_seen }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{# endif #}
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="profile__info__block">
|
||||||
|
<div class="profile__info__row">
|
||||||
|
<div class="profile__info__column profile__info__column--heading">
|
||||||
|
Topics
|
||||||
|
</div>
|
||||||
|
<div class="profile__info__column profile__info__column--numeric">
|
||||||
|
{{ profile.forum_topic_count }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="profile__info__row">
|
||||||
|
<div class="profile__info__column profile__info__column--heading">
|
||||||
|
Posts
|
||||||
|
</div>
|
||||||
|
<div class="profile__info__column profile__info__column--numeric">
|
||||||
|
{{ profile.forum_post_count }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue