summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--database.sql9
-rw-r--r--public/emotes/index.php17
-rw-r--r--public/emotes/upload.php6
-rw-r--r--public/system/emotes/index.php155
-rw-r--r--public/system/emotes/manip.php76
-rw-r--r--public/system/index.php68
-rw-r--r--src/config.php6
-rw-r--r--src/partials.php40
8 files changed, 362 insertions, 15 deletions
diff --git a/database.sql b/database.sql
index 1340d36..3f97ea3 100644
--- a/database.sql
+++ b/database.sql
@@ -105,4 +105,13 @@ CREATE TABLE IF NOT EXISTS role_assigns(
id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
user_id INTEGER NOT NULL UNIQUE REFERENCES users(id),
role_id INTEGER NOT NULL REFERENCES roles(id)
+);
+
+CREATE TABLE IF NOT EXISTS mod_actions(
+ id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
+ user_id INTEGER NOT NULL REFERENCES users(id),
+ emote_id INTEGER NOT NULL REFERENCES emotes(id),
+ verdict INTEGER NOT NULL,
+ comment TEXT,
+ created_at TIMESTAMP NOT NULL DEFAULT UTC_TIMESTAMP
); \ No newline at end of file
diff --git a/public/emotes/index.php b/public/emotes/index.php
index 1606b17..2102aba 100644
--- a/public/emotes/index.php
+++ b/public/emotes/index.php
@@ -357,10 +357,19 @@ if (CLIENT_REQUIRES_JSON) {
<tr>
<th>Visibility</th>
<td><?php
- if ($emote->get_visibility() == 1) {
- echo 'Public';
- } else {
- echo 'Unlisted';
+ switch ($emote->get_visibility()) {
+ case 0:
+ echo 'Unlisted';
+ break;
+ case 1:
+ echo 'Public';
+ break;
+ case 2:
+ echo 'Pending approval (unlisted for a moment)';
+ break;
+ default:
+ echo 'N/A';
+ break;
}
?></td>
</tr>
diff --git a/public/emotes/upload.php b/public/emotes/upload.php
index 5563323..50a8d15 100644
--- a/public/emotes/upload.php
+++ b/public/emotes/upload.php
@@ -220,7 +220,11 @@ if (is_null(list($mime, $ext) = get_mime_and_ext($image["tmp_name"]))) {
exit;
}
-$visibility = intval($_GET["visibility"], "0");
+$visibility = clamp(intval($_POST["visibility"], EMOTE_VISIBILITY_DEFAULT), 0, 2);
+
+if (MOD_EMOTES_APPROVE && $visibility == 1 && EMOTE_VISIBILITY_DEFAULT != 1) {
+ $visibility = 2;
+}
// creating a new emote record
$db = new PDO(DB_URL, DB_USER, DB_PASS);
diff --git a/public/system/emotes/index.php b/public/system/emotes/index.php
new file mode 100644
index 0000000..f49ff97
--- /dev/null
+++ b/public/system/emotes/index.php
@@ -0,0 +1,155 @@
+<?php
+include_once "../../../src/partials.php";
+include_once "../../../src/accounts.php";
+include_once "../../../src/alert.php";
+include_once "../../../src/config.php";
+include_once "../../../src/utils.php";
+
+if (!MOD_EMOTES_APPROVE) {
+ generate_alert("/404.php", "Manual emote approval is disabled", 405);
+ exit;
+}
+
+if (!authorize_user(true) || !$_SESSION["user_role"]["permission_approve_emotes"]) {
+ generate_alert("/404.php", "Not enough permissions", 403);
+ exit;
+}
+
+$emote_id = max(0, intval($_GET["id"] ?? "0"));
+
+$db = new PDO(DB_URL, DB_USER, DB_PASS);
+$emote_results = $db->query("SELECT e.*, u.username as uploader_name
+FROM emotes e
+LEFT JOIN users u ON u.id = e.uploaded_by
+WHERE e.visibility = 2
+ORDER BY e.created_at DESC
+LIMIT 25
+")->fetchAll(PDO::FETCH_ASSOC);
+
+$emote = $emote_results[0] ?? null;
+
+if ($emote_id > 0) {
+ $stmt = $db->prepare("SELECT e.*, u.username as uploader_name
+ FROM emotes e
+ LEFT JOIN users u ON u.id = e.uploaded_by
+ WHERE e.visibility = 2 AND e.id = ?
+ LIMIT 1");
+ $stmt->execute([$emote_id]);
+ $emote = $stmt->fetch(PDO::FETCH_ASSOC) ?? null;
+}
+
+?>
+
+<html>
+
+<head>
+ <title>System panel - alright.party</title>
+ <link rel="stylesheet" href="/static/style.css">
+</head>
+
+<body>
+ <div class="container">
+ <div class="wrapper">
+ <?php html_navigation_bar() ?>
+ <?php display_alert() ?>
+ <section class="content row">
+ <section class="box">
+ <div class="box navtab">System panel - Emote approval section</div>
+ <div class="box content">
+ <?php
+ foreach ($emote_results as $row) {
+ echo '<a href="/system/emotes?id=' . $row["id"] . '">';
+ echo '<img src="/static/userdata/emotes/' . $row["id"] . '/1x.' . $row["ext"] . '">';
+ echo '<b>' . $row["code"] . '</b>';
+ echo '<span style="font-size:10px;"> by ';
+
+ if ($row["uploader_name"] == null) {
+ echo ANONYMOUS_DEFAULT_NAME . '*';
+ } else {
+ echo $row["uploader_name"];
+ }
+
+ echo '</span></a>';
+ }
+
+ if (empty($emote_results)) {
+ echo 'Everything is clear. Good job!';
+ }
+ ?>
+ </div>
+ </section>
+ <?php if ($emote != null): ?>
+ <section class="content">
+ <!-- Emote showcase -->
+ <section class="box">
+ <div class="box navtab">Emote - <?php echo $emote["code"] ?></div>
+ <div class="box content">
+ <div class="emote-showcase">
+ <img src="/static/userdata/emotes/<?php echo $emote["id"] . '/' . '1x.' . $emote["ext"] ?>"
+ alt="<?php echo $emote["id"] ?>">
+ <img src="/static/userdata/emotes/<?php echo $emote["id"] . '/' . '2x.' . $emote["ext"] ?>"
+ alt="<?php echo $emote["id"] ?>">
+ <img src="/static/userdata/emotes/<?php echo $emote["id"] . '/' . '3x.' . $emote["ext"] ?>"
+ alt="<?php echo $emote["id"] ?>">
+ </div>
+ </div>
+ </section>
+ <!-- Emote actions -->
+ <section class="box items center row">
+ <form action="/system/emotes/manip.php" method="post">
+ <input type="text" name="id" value="<?php echo $emote["id"] ?>" style="display: none;">
+ <input type="text" name="action" value="approve" style="display: none;">
+ <button type="submit" class="green">Approve</button>
+ </form>
+ <form action="/system/emotes/manip.php" method="post">
+ <input type="text" name="id" value="<?php echo $emote["id"] ?>" style="display: none;">
+ <input type="text" name="action" value="reject" style="display: none;">
+ <button type="submit" class="red">Reject</button>
+ </form>
+ </section>
+ <!-- Emote information -->
+ <section class="box">
+ <table class="vertical">
+ <tr>
+ <th>Uploader</th>
+ <td><?php
+ $username = ANONYMOUS_DEFAULT_NAME;
+ $link = "#";
+
+ if ($row["uploader_name"] != null) {
+ $username = $row["uploader_name"];
+ $link = '/users.php?id=' . $row["uploaded_by"];
+ }
+
+ echo "<a href=\"$link\">";
+ echo $username;
+ echo "</a>";
+
+ echo ', <span title="';
+ echo date("M d, Y H:i:s", strtotime($row["created_at"]));
+ echo ' UTC">about ' . format_timestamp(time() - strtotime($row["created_at"])) . " ago</span>";
+ ?></td>
+ </tr>
+ <tr>
+ <th>Notes</th>
+ <td><i>Empty</i></td>
+ </tr>
+ </table>
+ </section>
+ <!-- Mod actions on emote -->
+ <section class="box">
+ <div class="box navtab">
+ Mod actions
+ </div>
+ <div class="box content">
+ <p>No one has done anything on this emote...</p>
+ </div>
+ </section>
+ </section>
+ <?php endif; ?>
+ </section>
+ </div>
+ </div>
+</body>
+
+</html> \ No newline at end of file
diff --git a/public/system/emotes/manip.php b/public/system/emotes/manip.php
new file mode 100644
index 0000000..2c04c3f
--- /dev/null
+++ b/public/system/emotes/manip.php
@@ -0,0 +1,76 @@
+<?php
+include_once "../../../src/alert.php";
+include_once "../../../src/accounts.php";
+include_once "../../../src/config.php";
+include_once "../../../src/utils.php";
+
+if (!MOD_EMOTES_APPROVE) {
+ generate_alert("/404.php", "Manual emote approval is disabled", 405);
+ exit;
+}
+
+if (!authorize_user(true) || !$_SESSION["user_role"]["permission_approve_emotes"]) {
+ generate_alert("/404.php", "Not enough permissions", 403);
+ exit;
+}
+
+if (!isset($_POST["id"], $_POST["action"])) {
+ generate_alert("/system/emotes", "Not enough POST fields");
+ exit;
+}
+
+$id = intval($_POST["id"], 0);
+$action = $_POST["action"];
+
+$db = new PDO(DB_URL, DB_USER, DB_PASS);
+
+$stmt = $db->prepare("SELECT id, code, uploaded_by FROM emotes WHERE id = ? AND visibility = 2 LIMIT 1");
+$stmt->execute([$id]);
+
+if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
+ $verdict = 2;
+
+ switch ($action) {
+ case "approve": {
+ $db->prepare("UPDATE emotes SET visibility = 1 WHERE id = ?")
+ ->execute([$row["id"]]);
+ $verdict = 1;
+ break;
+ }
+ case "reject": {
+ $db->prepare("UPDATE emotes SET visibility = 0 WHERE id = ?")
+ ->execute([$row["id"]]);
+ $verdict = 0;
+ break;
+ }
+ default: {
+ generate_alert("/system/emotes", "Unknown action");
+ exit;
+ }
+ }
+
+ $comment = str_safe($_POST["comment"] ?? "", EMOTE_COMMENT_MAX_LENGTH, false);
+
+ if ($comment == "") {
+ $comment = null;
+ }
+
+ $db->prepare("INSERT INTO mod_actions(user_id, emote_id, verdict, comment) VALUES (?, ?, ?, ?)")
+ ->execute([$_SESSION["user_id"], $row["id"], $verdict, $comment]);
+
+ if ($row["uploaded_by"] != null) {
+ $contents = match ($verdict) {
+ 0 => 'Your emote "' . $row["code"] . '" has been unlisted! Anyone can add it via a direct link.',
+ 1 => 'Your emote "' . $row["code"] . '" has been approved! Enjoy!',
+ default => 'We did something with your emote "' . $row["code"] . '"'
+ };
+
+ $db->prepare("INSERT INTO inbox_messages(recipient_id, message_type, contents, link) VALUES (?, ?, ?, ?)")
+ ->execute([$row["uploaded_by"], "1", $contents, "/emotes?id=" . $row["id"]]);
+ }
+
+ generate_alert("/system/emotes", 'Emote "' . $row["code"] . '" has been ' . ($verdict == 0 ? 'rejected (unlisted)' : 'approved (public)') . '!', 200);
+ exit;
+}
+
+generate_alert("system/emotes", "Emote ID $id not found", 404); \ No newline at end of file
diff --git a/public/system/index.php b/public/system/index.php
new file mode 100644
index 0000000..aa959c0
--- /dev/null
+++ b/public/system/index.php
@@ -0,0 +1,68 @@
+<?php
+include_once "../../src/partials.php";
+include_once "../../src/accounts.php";
+include_once "../../src/alert.php";
+include_once "../../src/config.php";
+
+if (!MOD_SYSTEM_DASHBOARD) {
+ generate_alert("/404.php", "System dashboard is disabled", 405);
+ exit;
+}
+
+if (!authorize_user(true) || (!$_SESSION["user_role"]["permission_approve_emotes"] && !$_SESSION["user_role"]["permission_report_review"])) {
+ generate_alert("/404.php", "Not enough permissions", 403);
+ exit;
+}
+
+$db = new PDO(DB_URL, DB_USER, DB_PASS);
+
+?>
+
+<html>
+
+<head>
+ <title>System panel - alright.party</title>
+ <link rel="stylesheet" href="/static/style.css">
+</head>
+
+<body>
+ <div class="container">
+ <div class="wrapper">
+ <?php html_navigation_bar() ?>
+ <section class="content">
+ <section class="box">
+ <div class="box navtab">System panel</div>
+ <div class="box content">
+ <?php
+ if (MOD_EMOTES_APPROVE && $_SESSION["user_role"]["permission_approve_emotes"]) {
+ echo '<a href="/system/emotes">Emotes';
+
+ $results = $db->query("SELECT COUNT(*) FROM emotes WHERE visibility = 2")->fetch()[0];
+
+ if ($results > 0) {
+ echo " ($results pending)";
+ }
+
+ echo '</a>';
+ }
+
+ if ($_SESSION["user_role"]["permission_report_review"]) {
+ echo '<a href="/system/reports">Reports';
+
+ $results = $db->query("SELECT COUNT(*) FROM reports WHERE resolved_by IS NULL")->fetch()[0];
+
+ if ($results > 0) {
+ echo " ($results pending)";
+ }
+
+ echo '</a>';
+ }
+ ?>
+ </div>
+ </section>
+ </section>
+ </div>
+ </div>
+</body>
+
+</html> \ No newline at end of file
diff --git a/src/config.php b/src/config.php
index d75e9f1..f5056ce 100644
--- a/src/config.php
+++ b/src/config.php
@@ -18,6 +18,12 @@ define("ANONYMOUS_DEFAULT_NAME", "chud");
// EMOTES
define("EMOTE_NAME_MAX_LENGTH", 100);
+define("EMOTE_COMMENT_MAX_LENGTH", 100);
+define("EMOTE_VISIBILITY_DEFAULT", 2);
+
+// MODERATION
+define("MOD_SYSTEM_DASHBOARD", true);
+define("MOD_EMOTES_APPROVE", true);
// ACCOUNTS
define("ACCOUNT_USERNAME_REGEX", "/^[A-Za-z0-9_]+$/");
diff --git a/src/partials.php b/src/partials.php
index 9b02a7b..2a560df 100644
--- a/src/partials.php
+++ b/src/partials.php
@@ -30,17 +30,37 @@ function html_navigation_bar()
<?php ;
$stmt = null;
- if (isset($_SESSION["user_role"]) && $_SESSION["user_role"]["permission_report"]) {
- // getting reports
- $stmt = $db->prepare("SELECT COUNT(*) FROM reports WHERE sender_id = ? AND resolved_by IS NULL");
- $stmt->execute([$_SESSION["user_id"]]);
- $unread_count = intval($stmt->fetch()[0]);
+ if (isset($_SESSION["user_role"])) {
+ if ($_SESSION["user_role"]["permission_report"]) {
+ // getting reports
+ $stmt = $db->prepare("SELECT COUNT(*) FROM reports WHERE sender_id = ? AND resolved_by IS NULL");
+ $stmt->execute([$_SESSION["user_id"]]);
+ $unread_count = intval($stmt->fetch()[0]);
- echo '' ?>
- <a href="/report/list.php" class="button">
- Reports <?php echo $unread_count > 0 ? "($unread_count)" : "" ?>
- </a>
- <?php ;
+ echo '' ?>
+ <a href="/report/list.php" class="button">
+ Reports <?php echo $unread_count > 0 ? "($unread_count)" : "" ?>
+ </a>
+ <?php ;
+ }
+
+ if (MOD_SYSTEM_DASHBOARD && ($_SESSION["user_role"]["permission_approve_emotes"] || $_SESSION["user_role"]["permission_report_review"])) {
+ $system_count = 0;
+
+ if ($_SESSION["user_role"]["permission_approve_emotes"] && MOD_EMOTES_APPROVE) {
+ $system_count += intval($db->query("SELECT COUNT(*) FROM emotes WHERE visibility = 2")->fetch()[0]);
+ }
+
+ if ($_SESSION["user_role"]["permission_report_review"]) {
+ $system_count += intval($db->query("SELECT COUNT(*) FROM reports WHERE resolved_by IS NULL")->fetch()[0]);
+ }
+
+ echo '<a href="/system" class="button">System';
+ if ($system_count > 0) {
+ echo " ($system_count)";
+ }
+ echo '</a>';
+ }
}
$stmt = null;