summaryrefslogtreecommitdiff
path: root/public
diff options
context:
space:
mode:
authorilotterytea <iltsu@alright.party>2025-12-08 21:53:36 +0500
committerilotterytea <iltsu@alright.party>2025-12-08 21:53:36 +0500
commit57472eab3c7b035392c6a5aa240593ecaa7d1ccf (patch)
tree9da30829290f225be2dab3d383549cbfda82ed19 /public
parent6541d0f3888862ab049055fd418b700f73eed367 (diff)
upd: moved all /public/ files to the root folder
Diffstat (limited to 'public')
-rw-r--r--public/404.php43
-rw-r--r--public/account/change_emoteset.php36
-rw-r--r--public/account/delete.php50
-rw-r--r--public/account/index.php306
-rw-r--r--public/account/login/index.php99
-rw-r--r--public/account/login/twitch.php175
-rw-r--r--public/account/register.php111
-rw-r--r--public/account/security.php52
-rw-r--r--public/account/signout.php16
-rw-r--r--public/badges.php50
-rw-r--r--public/captcha.php59
-rw-r--r--public/emotes/delete.php47
-rw-r--r--public/emotes/index.php546
-rw-r--r--public/emotes/rate.php63
-rw-r--r--public/emotes/setmanip.php138
-rw-r--r--public/emotes/upload.php552
-rw-r--r--public/emotesets.php164
-rw-r--r--public/inbox.php77
-rw-r--r--public/index.php90
-rw-r--r--public/report/index.php124
-rw-r--r--public/report/list.php81
-rw-r--r--public/report/send.php45
-rw-r--r--public/rules.php50
-rw-r--r--public/software.php83
-rw-r--r--public/static/favicon.icobin1150 -> 0 bytes
-rw-r--r--public/static/img/404/1.webpbin279856 -> 0 bytes
-rw-r--r--public/static/img/brand/big.webpbin12592 -> 0 bytes
-rw-r--r--public/static/img/brand/mini.webpbin3244 -> 0 bytes
-rw-r--r--public/static/img/counter/0.pngbin37146 -> 0 bytes
-rw-r--r--public/static/img/counter/1.pngbin32791 -> 0 bytes
-rw-r--r--public/static/img/counter/2.pngbin37615 -> 0 bytes
-rw-r--r--public/static/img/counter/3.pngbin22557 -> 0 bytes
-rw-r--r--public/static/img/counter/4.pngbin35197 -> 0 bytes
-rw-r--r--public/static/img/counter/5.pngbin20349 -> 0 bytes
-rw-r--r--public/static/img/counter/6.pngbin32075 -> 0 bytes
-rw-r--r--public/static/img/counter/7.pngbin22028 -> 0 bytes
-rw-r--r--public/static/img/counter/8.pngbin34637 -> 0 bytes
-rw-r--r--public/static/img/counter/9.pngbin142919 -> 0 bytes
-rw-r--r--public/static/img/defaults/profile_picture.pngbin29739 -> 0 bytes
-rw-r--r--public/static/img/icons/bin.pngbin475 -> 0 bytes
-rw-r--r--public/static/img/icons/clock.pngbin882 -> 0 bytes
-rw-r--r--public/static/img/icons/connect.pngbin748 -> 0 bytes
-rw-r--r--public/static/img/icons/connections/twitch.webpbin5142 -> 0 bytes
-rw-r--r--public/static/img/icons/disconnect.pngbin796 -> 0 bytes
-rw-r--r--public/static/img/icons/door_in.pngbin693 -> 0 bytes
-rw-r--r--public/static/img/icons/door_out.pngbin688 -> 0 bytes
-rw-r--r--public/static/img/icons/emotes/emote.pngbin4877 -> 0 bytes
-rw-r--r--public/static/img/icons/emotes/emote_folder.pngbin4885 -> 0 bytes
-rw-r--r--public/static/img/icons/emotes/emote_go.pngbin4980 -> 0 bytes
-rw-r--r--public/static/img/icons/emoticon_happy.pngbin731 -> 0 bytes
-rw-r--r--public/static/img/icons/eye.pngbin750 -> 0 bytes
-rw-r--r--public/static/img/icons/heart.pngbin749 -> 0 bytes
-rw-r--r--public/static/img/icons/inbox/0.pngbin587 -> 0 bytes
-rw-r--r--public/static/img/icons/inbox/1.pngbin781 -> 0 bytes
-rw-r--r--public/static/img/icons/inbox/2.pngbin641 -> 0 bytes
-rw-r--r--public/static/img/icons/link_break.pngbin657 -> 0 bytes
-rw-r--r--public/static/img/icons/new_emote.pngbin963 -> 0 bytes
-rw-r--r--public/static/img/icons/no.pngbin587 -> 0 bytes
-rw-r--r--public/static/img/icons/pencil.pngbin450 -> 0 bytes
-rw-r--r--public/static/img/icons/ratings/-1.pngbin573 -> 0 bytes
-rw-r--r--public/static/img/icons/ratings/1.pngbin883 -> 0 bytes
-rw-r--r--public/static/img/icons/ratings/brimstone.webpbin8400 -> 0 bytes
-rw-r--r--public/static/img/icons/star.pngbin670 -> 0 bytes
-rw-r--r--public/static/img/icons/table.pngbin566 -> 0 bytes
-rw-r--r--public/static/img/icons/tag_blue.pngbin586 -> 0 bytes
-rw-r--r--public/static/img/icons/user.pngbin741 -> 0 bytes
-rw-r--r--public/static/img/icons/world.pngbin923 -> 0 bytes
-rw-r--r--public/static/img/icons/yes.pngbin781 -> 0 bytes
-rw-r--r--public/static/img/software/tinyrino/icon.pngbin6845 -> 0 bytes
-rw-r--r--public/static/img/software/tinyrino/screenshots/1.pngbin57921 -> 0 bytes
-rw-r--r--public/static/img/software/tinyrino/screenshots/2.pngbin197187 -> 0 bytes
-rw-r--r--public/static/style.css640
-rw-r--r--public/static/txt/RULES2
-rw-r--r--public/system/emotes/index.php250
-rw-r--r--public/system/emotes/verdict.php80
-rw-r--r--public/system/index.php69
-rw-r--r--public/users.php587
77 files changed, 0 insertions, 4685 deletions
diff --git a/public/404.php b/public/404.php
deleted file mode 100644
index cd7e12e..0000000
--- a/public/404.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-include_once "../src/config.php";
-include_once "../src/utils.php";
-include_once "../src/partials.php";
-include_once "../src/accounts.php";
-
-authorize_user();
-
-$status = intval($_GET["error_status"] ?? "404");
-http_response_code($status);
-
-$reason = str_safe($_GET["error_reason"] ?? "Not found", 200);
-
-?>
-<html>
-
-<head>
- <title>(Error) <?php echo sprintf("%s - %s", $reason, INSTANCE_NAME) ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
- <section class="content">
- <h1 style="color: red;"><?php echo $reason ?></h1>
- <a href="/">[ Back to home ]</a>
- </section>
-
- <section style="position: absolute; right: 6px; bottom: 6px;">
- <img src="/static/img/404/<?php
- $files = scandir(INSTANCE_STATIC_FOLDER . "/img/404");
- array_splice($files, 0, 2);
- echo $files[random_int(0, count($files) - 1)];
- ?>" alt=""></img>
- </section>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/account/change_emoteset.php b/public/account/change_emoteset.php
deleted file mode 100644
index c2fc209..0000000
--- a/public/account/change_emoteset.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-include_once "../../src/config.php";
-include_once "../../src/alert.php";
-include_once "../../src/accounts.php";
-
-if (!authorize_user(true)) {
- generate_alert("/404.php", "Unauthorized", 401);
- exit;
-}
-
-if ($_SERVER["REQUEST_METHOD"] != "POST") {
- generate_alert("/404.php", "Method not allowed", 405);
- exit;
-}
-
-if (!isset($_POST["id"])) {
- generate_alert("/404.php", "Emote set ID is not provided");
- exit;
-}
-
-$emote_set_id = $_POST["id"];
-$user_id = $_SESSION["user_id"];
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-$stmt = $db->prepare("SELECT id FROM acquired_emote_sets WHERE emote_set_id = ? AND user_id = ?");
-$stmt->execute([$emote_set_id, $user_id]);
-
-if ($stmt->rowCount() == 0) {
- generate_alert("/404.php", "You don't own emote set ID $emote_set_id", 403);
- exit;
-}
-
-$_SESSION["user_active_emote_set_id"] = $emote_set_id;
-
-header("Location: " . $_POST["redirect"] ?? "/"); \ No newline at end of file
diff --git a/public/account/delete.php b/public/account/delete.php
deleted file mode 100644
index ec8c040..0000000
--- a/public/account/delete.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-include "../../src/utils.php";
-include_once "../../src/config.php";
-
-session_start();
-
-if (!isset($_SESSION["user_id"])) {
- header("Location: /account");
- exit;
-}
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-$id = $_SESSION["user_id"];
-
-$profile = ($_GET["profile"] ?? "false") == "true";
-$pfp = ($_GET["pfp"] ?? "false") == "true";
-$banner = ($_GET["banner"] ?? "false") == "true";
-$badge = ($_GET["badge"] ?? "false") == "true";
-
-if ($pfp || $profile) {
- $path = "../static/userdata/avatars/$id";
- if (is_dir($path)) {
- array_map("unlink", glob("$path/*.*"));
- rmdir($path);
- }
-}
-
-if ($banner || $profile) {
- $path = "../static/userdata/banners/$id";
- if (is_dir($path)) {
- array_map("unlink", glob("$path/*.*"));
- rmdir($path);
- }
-}
-
-if ($badge || $profile) {
- $db->prepare("DELETE FROM user_badges WHERE user_id = ?")->execute([$id]);
-}
-
-if ($profile) {
- $db->prepare("DELETE FROM users WHERE id = ?")->execute([$id]);
-
- session_unset();
- session_destroy();
-
- setcookie("secret_key", "", time() - 1000);
-}
-
-header("Location: /account"); \ No newline at end of file
diff --git a/public/account/index.php b/public/account/index.php
deleted file mode 100644
index 2b9e790..0000000
--- a/public/account/index.php
+++ /dev/null
@@ -1,306 +0,0 @@
-<?php
-include_once "../../src/alert.php";
-include "../../src/accounts.php";
-include "../../src/partials.php";
-include_once "../../src/config.php";
-include_once "../../src/utils.php";
-include_once "../../src/images.php";
-
-authorize_user();
-
-if (!isset($_SESSION["user_id"], $_SESSION["user_name"])) {
- header("Location: /account/login");
- exit;
-}
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-if ($_SERVER['REQUEST_METHOD'] == "POST") {
- $username = str_safe($_POST["username"] ?? "", ACCOUNT_USERNAME_LENGTH[1]);
-
- if (!empty($username) && $username != $_SESSION["user_name"]) {
- if (!preg_match(ACCOUNT_USERNAME_REGEX, $username)) {
- generate_alert("/account", "Bad username");
- exit;
- }
-
- $stmt = $db->prepare("SELECT id FROM users WHERE username = ?");
- $stmt->execute([$username]);
-
- if ($stmt->rowCount() == 0) {
- $stmt = $db->prepare("UPDATE users SET username = ? WHERE id = ?");
- $stmt->execute([$username, $_SESSION["user_id"]]);
- } else {
- generate_alert("/account", "The username has already taken");
- exit;
- }
- }
-
- if (isset($_FILES["pfp"]) && !empty($_FILES["pfp"]["tmp_name"])) {
- $pfp = $_FILES["pfp"];
-
- if (
- $err = create_image_bundle(
- $pfp["tmp_name"],
- $_SERVER["DOCUMENT_ROOT"] . "/static/userdata/avatars/" . $_SESSION["user_id"],
- ACCOUNT_PFP_MAX_SIZE[0],
- ACCOUNT_PFP_MAX_SIZE[1],
- true,
- true
- )
- ) {
- generate_alert("/account", sprintf("Error occurred while processing the profile picture (%d)", $err));
- exit;
- }
- }
-
- if (isset($_FILES["banner"]) && !empty($_FILES["banner"]["tmp_name"])) {
- $banner = $_FILES["banner"];
-
- if (
- $err = create_image_bundle(
- $banner["tmp_name"],
- $_SERVER["DOCUMENT_ROOT"] . "/static/userdata/banners/" . $_SESSION["user_id"],
- ACCOUNT_BANNER_MAX_SIZE[0],
- ACCOUNT_BANNER_MAX_SIZE[1],
- true,
- true
- )
- ) {
- generate_alert("/account", sprintf("Error occurred while processing the profile banner (%d)", $err));
- exit;
- }
- }
-
- if (isset($_FILES["badge"]) && !empty($_FILES["badge"]["tmp_name"])) {
- $badge = $_FILES["badge"];
- $badge_id = bin2hex(random_bytes(16));
- if (
- $err = create_image_bundle(
- $badge["tmp_name"],
- $_SERVER["DOCUMENT_ROOT"] . "/static/userdata/badges/" . $badge_id,
- ACCOUNT_BADGE_MAX_SIZE[0],
- ACCOUNT_BADGE_MAX_SIZE[1],
- true,
- true
- )
- ) {
- generate_alert("/account", sprintf("Error occurred while processing the personal badge (%d)", $err));
- exit;
- }
-
- $db->prepare("DELETE FROM user_badges WHERE badge_id != ? AND user_id = ?")->execute([$badge_id, $_SESSION["user_id"]]);
- $db->prepare("INSERT INTO badges(id, uploaded_by) VALUES (?, ?)")->execute([$badge_id, $_SESSION["user_id"]]);
- $db->prepare("INSERT INTO user_badges(badge_id, user_id) VALUES (?, ?)")->execute([$badge_id, $_SESSION["user_id"]]);
- }
-
- $db = null;
- generate_alert("/account", "Your changes have been applied!", 200);
- exit;
-}
-
-?>
-
-<html>
-
-<head>
- <title>Account management - <?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
-
- <section class="content">
- <?php display_alert() ?>
- <section class="box accman">
- <h1>Account management</h1>
-
- <form action="/account/" method="POST" enctype="multipart/form-data">
- <h2>Profile</h2>
- <h3>Profile picture</h3>
- <?php
- $has_pfp = is_dir("../static/userdata/avatars/" . $_SESSION["user_id"]);
- if ($has_pfp) {
- echo '<img src="/static/userdata/avatars/' . $_SESSION["user_id"] . '/2x.webp" id="pfp" width="64" height="64">';
- } else {
- echo "<p>You don't have profile picture</p>";
- }
- ?>
- <div>
- <input type="file" name="pfp">
- <?php if ($has_pfp): ?>
- <a href="/account/delete.php?pfp=true">
- <img src="/static/img/icons/bin.png" alt="Remove profile picture"
- title="Remove profile picture">
- </a>
- <?php endif; ?>
- </div>
-
- <h3>Profile banner</h3>
- <?php
- $has_banner = is_dir("../static/userdata/banners/" . $_SESSION["user_id"]);
- if ($has_banner) {
- echo '<img src="/static/userdata/banners/' . $_SESSION["user_id"] . '/2x.webp" id="banner" width="256">';
- } else {
- echo "<p>You don't have profile banner</p>";
- }
- ?>
- <div>
- <input type="file" name="banner">
- <?php if ($has_banner): ?>
- <a href="/account/delete.php?banner=true">
- <img src="/static/img/icons/bin.png" alt="Remove banner" title="Remove banner">
- </a>
- <?php endif; ?>
- </div>
-
- <h3>Personal badge</h3>
- <?php
- $stmt = $db->prepare("SELECT badge_id FROM user_badges WHERE user_id = ?");
- $stmt->execute([$_SESSION["user_id"]]);
-
- $has_badge = false;
-
- if ($row = $stmt->fetch()) {
- echo '<div class="box row items-center justify-between">';
- echo '<img src="/static/userdata/badges/' . $row["badge_id"] . '/1x.webp" id="badge">';
- echo '<img src="/static/userdata/badges/' . $row["badge_id"] . '/2x.webp" id="badge">';
- echo '<img src="/static/userdata/badges/' . $row["badge_id"] . '/3x.webp" id="badge">';
- echo '</div>';
- $has_badge = true;
- } else {
- echo "<p>You don't have personal badge</p>";
- }
- ?>
- <div>
- <input type="file" name="badge">
- <?php if ($has_badge): ?>
- <a href="/account/delete.php?badge=true">
- <img src="/static/img/icons/bin.png" alt="Remove badge" title="Remove badge">
- </a>
- <?php endif; ?>
- </div>
-
- <h3>Username</h3>
- <input type="text" name="username" id="username" value="<?php echo $_SESSION["user_name"] ?>">
-
- <button type="submit">Save</button>
- </form>
-
- <hr>
-
- <div>
- <h2>Connections</h2>
- <div>
- <?php
- $stmt = $db->prepare("SELECT * FROM connections WHERE user_id = ?");
- $stmt->execute([$_SESSION["user_id"]]);
- $connections = $stmt->fetchAll();
- $platforms = ["twitch"];
-
- foreach ($platforms as $platform) {
- $connection = null;
- $key = array_search($platform, array_column($connections, "platform"));
-
- if (!is_bool($key)) {
- $connection = $connections[$key];
- }
-
- echo "<div class='box $platform row small-gap items-center'>";
- echo "<div><img src='/static/img/icons/connections/$platform.webp' alt='' width='52' height='52' /></div>";
-
- echo "<div class='column grow'>";
- echo "<b>" . ucfirst($platform) . "</b>";
-
- // TODO: check if connection is still alive
- if ($connection == null) {
- echo "<i>Not connected</i>";
- } else {
- echo "<i>" . $connection["alias_id"] . "</i>";
- }
-
- echo "</div>";
-
- echo "<div class='column'>";
-
- if ($connection == null) {
- echo "<a href='/account/login/$platform.php'>";
- echo '<img src="/static/img/icons/disconnect.png" alt="Connect" title="Connect" />';
- echo "</a>";
- } else {
- echo "<a href='/account/login/$platform.php?disconnect'>";
- echo '<img src="/static/img/icons/connect.png" alt="Disconnect" title="Disconnect" />';
- echo "</a>";
- }
-
- echo "</div></div>";
- }
- ?>
- </div>
- </div>
-
- <hr>
-
- <form action="/account/security.php" method="post">
- <h2>Security & Privacy</h2>
- <div>
- <?php
- $stmt = $db->prepare("SELECT CASE WHEN password IS NOT NULL THEN 1 ELSE 0 END as set_password FROM users WHERE id = ?");
- $stmt->execute([$_SESSION["user_id"]]);
- $set_password = $stmt->fetch()[0];
- if ($set_password): ?>
- <label for="password-current">Current password:</label>
- <input type="password" name="password-current" id="form-password-current" required>
- <?php endif; ?>
- <label for="password-new">New password:</label>
- <input type="password" name="password-new" id="form-password-new">
- </div>
- <div>
- <input type="checkbox" name="make-private" value="1" id="form-make-private" <?php
- $stmt = $db->prepare("SELECT private_profile FROM user_preferences WHERE id = ?");
- $stmt->execute([$_SESSION["user_id"]]);
- if (intval($stmt->fetch()[0]) == 1) {
- echo 'checked';
- }
- ?>>
- <label for="make-private" class="inline">Make profile private</label>
- <p class="font-small">Enabling this feature will hide your authorship of uploaded emotes and
- actions.</p>
-
- </div>
- <div>
- <input type="checkbox" name="signout-everywhere" value="1" id="form-signout-everywhere">
- <label for="signout-everywhere" class="inline">Sign out everywhere</label>
- </div>
-
- <button type="submit">Apply</button>
- </form>
-
- <a href="/account/delete.php?profile=true" class="red button" style="text-align: center;">Delete
- me</a>
- </section>
- </section>
- </div>
- </div>
-</body>
-
-<script>
- const username = document.getElementById("username");
- let validUsername = "";
-
- username.addEventListener("input", (e) => {
- const regex = <?php echo ACCOUNT_USERNAME_REGEX ?>;
-
- if (regex.test(e.target.value) && e.target.value.length <= <?php echo ACCOUNT_USERNAME_LENGTH[1] ?>) {
- validUsername = e.target.value;
- } else {
- e.target.value = validUsername;
- }
- });
-</script>
-
-</html> \ No newline at end of file
diff --git a/public/account/login/index.php b/public/account/login/index.php
deleted file mode 100644
index ace116d..0000000
--- a/public/account/login/index.php
+++ /dev/null
@@ -1,99 +0,0 @@
-<?php
-include "../../../src/accounts.php";
-
-if (authorize_user()) {
- header("Location: /account");
- exit;
-}
-
-include "../../../src/partials.php";
-include_once "../../../src/config.php";
-include_once "../../../src/alert.php";
-include_once "../../../src/utils.php";
-
-if ($_SERVER["REQUEST_METHOD"] == "POST") {
- if (!isset($_POST["username"], $_POST["password"])) {
- generate_alert("/account/login", "Not enough POST fields");
- exit;
- }
-
- $username = $_POST["username"];
- $password = $_POST["password"];
- $remember = intval($_POST["remember"] ?? "0") != 0;
-
- $db = new PDO(DB_URL, DB_USER, DB_PASS);
- $stmt = $db->prepare("SELECT secret_key, password FROM users WHERE username = ? AND password IS NOT NULL");
- $stmt->execute([$username]);
-
- if ($row = $stmt->fetch()) {
- if (password_verify($password, $row["password"])) {
- setcookie("secret_key", $row["secret_key"], $remember ? (time() + ACCOUNT_COOKIE_MAX_LIFETIME) : 0, "/");
- header("Location: /account");
- exit;
- } else {
- generate_alert("/account/login", "Passwords do not match!", 403);
- exit;
- }
- } else {
- generate_alert("/account/login", "User not found or is not accessable", 404);
- exit;
- }
-}
-?>
-
-<html>
-
-<head>
- <title>Login - <?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar(); ?>
- <section class="content" style="width: 400px;">
- <?php display_alert() ?>
- <section class="box">
- <div class="box navtab">
- <p>Log in to <?php echo INSTANCE_NAME ?></p>
- </div>
- <div class="box content">
- <form action="/account/login/" method="post">
- <div>
- <label for="username">Username</label>
- <input type="text" name="username" id="form-username" required>
- </div>
- <div>
- <label for="password">Password</label>
- <input type="password" name="password" id="form-password" required>
- </div>
- <div>
- <input type="checkbox" name="remember" value="1" id="form-remember">
- <label for="remember" class="inline">Remember me</label>
- </div>
- <div>
- <button type="submit">Log in</button>
- <?php if (ACCOUNT_REGISTRATION_ENABLE): ?>
- <a href="/account/register.php">Register</a>
- <?php endif; ?>
- </div>
- </form>
- </div>
- </section>
-
- <?php if (TWITCH_REGISTRATION_ENABLE): ?>
- <section class="box column">
- <a href="/account/login/twitch.php" class="button purple big">Login with Twitch</a>
- <p style="font-size: 12px;">Logging in via Twitch gives you the ability to use
- <?php echo INSTANCE_NAME ?> emotes in your Twitch chat.
- </p>
- </section>
- <?php endif; ?>
- </section>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/account/login/twitch.php b/public/account/login/twitch.php
deleted file mode 100644
index 38fd6cc..0000000
--- a/public/account/login/twitch.php
+++ /dev/null
@@ -1,175 +0,0 @@
-<?php
-include_once "../../../src/config.php";
-include_once "../../../src/utils.php";
-include_once "../../../src/alert.php";
-
-if (!TWITCH_REGISTRATION_ENABLE) {
- generate_alert("/404.php", "Registration via Twitch is disabled", 405);
- exit;
-}
-
-session_start();
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-if (isset($_GET["disconnect"], $_SESSION["user_id"])) {
- $stmt = $db->prepare("SELECT c.id,
- CASE WHEN (
- SELECT u.password FROM users u WHERE u.id = c.user_id
- ) IS NOT NULL
- THEN 1 ELSE 0
- END AS set_password
- FROM connections c
- WHERE c.user_id = ?
- ");
- $stmt->execute([$_SESSION["user_id"]]);
-
- if ($row = $stmt->fetch()) {
- if ($row["set_password"]) {
- $db->prepare("DELETE FROM connections WHERE user_id = ? AND platform = 'twitch'")->execute([$_SESSION["user_id"]]);
- generate_alert("/account", "Successfully disconnected from Twitch!", 200);
- } else {
- generate_alert("/account", "You must set a password before deleting any connections", 403);
- }
- } else {
- generate_alert("/account", "No Twitch connection found", 404);
- }
- exit;
-}
-
-$client_id = TWITCH_CLIENT_ID;
-$client_secret = TWITCH_SECRET_KEY;
-$redirect_uri = TWITCH_REDIRECT_URI;
-
-if (isset($_GET["error"])) {
- header("Location: /account/login");
- exit;
-}
-
-if (!isset($_GET["code"])) {
- header("Location: https://id.twitch.tv/oauth2/authorize?client_id=$client_id&redirect_uri=$redirect_uri&response_type=code");
- exit;
-}
-
-$code = $_GET["code"];
-
-// obtaining twitch token
-$request = curl_init();
-curl_setopt($request, CURLOPT_URL, "https://id.twitch.tv/oauth2/token");
-curl_setopt($request, CURLOPT_POST, 1);
-curl_setopt(
- $request,
- CURLOPT_POSTFIELDS,
- "client_id=$client_id&client_secret=$client_secret&code=$code&grant_type=authorization_code&redirect_uri=$redirect_uri"
-);
-curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
-
-$response = curl_exec($request);
-curl_close($request);
-
-$response = json_decode($response, true);
-
-if (array_key_exists("status", $response)) {
- header("Location: /account/login");
- exit;
-}
-
-// identifying user
-$request = curl_init();
-curl_setopt($request, CURLOPT_URL, "https://api.twitch.tv/helix/users");
-curl_setopt($request, CURLOPT_HTTPHEADER, [
- "Authorization: Bearer " . $response["access_token"],
- "Client-Id: $client_id"
-]);
-curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
-
-$twitch_user = curl_exec($request);
-curl_close($request);
-
-$twitch_user = json_decode($twitch_user, true);
-
-if (empty($twitch_user["data"])) {
- generate_alert("/account", "Failed to identify Twitch user", 500);
- exit;
-}
-
-$twitch_user = $twitch_user["data"][0];
-
-// saving it
-$twitch_access_token = $response["access_token"];
-$twitch_refresh_token = $response["refresh_token"];
-$twitch_expires_on = time() + intval($response["expires_in"]);
-
-// creating user if not exists
-$stmt = $db->prepare("SELECT * FROM users u
- INNER JOIN connections c ON c.alias_id = ?
- WHERE c.user_id = u.id AND c.platform = 'twitch'
-");
-$stmt->execute([$twitch_user["id"]]);
-
-$user_id = "";
-$user_secret_key = "";
-$user_name = "";
-
-if ($row = $stmt->fetch()) {
- if (isset($_SESSION["user_id"]) && $_SESSION["user_id"] != $row["id"]) {
- generate_alert("/account", "There is another " . INSTANCE_NAME . " account associated with that Twitch account", 409);
- exit;
- }
-
- $user_name = $row["username"];
- $user_secret_key = $row["secret_key"];
- $user_id = $row["id"];
-} else {
- $user_secret_key = generate_random_string(32);
- $user_name = $twitch_user["login"];
- $user_id = bin2hex(random_bytes(16));
-
- list($user_secret_key, $user_name, $user_id) = match (isset($_SESSION["user_id"])) {
- true => [$_COOKIE["secret_key"], $_SESSION["user_name"], $_SESSION["user_id"]],
- default => [generate_random_string(32), $twitch_user["login"], bin2hex(random_bytes(16))]
- };
-
- if (!isset($_SESSION["user_id"])) {
- // checking for duplicates
- $stmt = $db->prepare("SELECT COUNT(*) FROM users WHERE username = ?");
- $stmt->execute([$user_name]);
- $duplicates = intval($stmt->fetch()[0]);
- if ($duplicates > 0) {
- $i = 1;
- while (true) {
- $stmt = $db->prepare("SELECT COUNT(*) FROM users WHERE username = ?");
- $stmt->execute(["$user_name$i"]);
-
- if ($stmt->fetch()[0] == 0) {
- break;
- }
-
- $i++;
- }
- $user_name .= $i;
- }
-
- $stmt = $db->prepare("INSERT INTO users(id, username, secret_key) VALUES (?, ?, ?)");
- if (!$stmt->execute([$user_id, $user_name, $user_secret_key])) {
- $db = null;
- echo "Failed to create a user";
- exit;
- }
- }
-
- $stmt = $db->prepare("INSERT INTO connections(user_id, alias_id, platform, data) VALUES (?, ?, 'twitch', ?)");
- $stmt->execute([
- $user_id,
- $twitch_user["id"],
- sprintf("%s:%s:%s", $twitch_access_token, $twitch_refresh_token, $twitch_expires_on)
- ]);
-}
-
-$_SESSION["user_id"] = $user_id;
-$_SESSION["user_name"] = $user_name;
-setcookie("secret_key", $user_secret_key, time() + ACCOUNT_COOKIE_MAX_LIFETIME, "/");
-
-$db = null;
-
-header("Location: /account"); \ No newline at end of file
diff --git a/public/account/register.php b/public/account/register.php
deleted file mode 100644
index 1da89a0..0000000
--- a/public/account/register.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-include "../../src/accounts.php";
-include_once "../../src/alert.php";
-
-if (authorize_user()) {
- header("Location: /account");
- exit;
-}
-
-if (!ACCOUNT_REGISTRATION_ENABLE) {
- generate_alert("/404.php", "Account registration is disabled", 403);
- exit;
-}
-
-include "../../src/partials.php";
-include_once "../../src/config.php";
-include_once "../../src/utils.php";
-
-if ($_SERVER["REQUEST_METHOD"] == "POST") {
- if (!isset($_POST["username"], $_POST["password"])) {
- generate_alert("/account/register.php", "Not enough POST fields");
- exit;
- }
-
- $username = $_POST["username"];
- $username_length = strlen($username);
- if (ACCOUNT_USERNAME_LENGTH[0] > $username_length || $username_length > ACCOUNT_USERNAME_LENGTH[1]) {
- generate_alert("/account/register.php", sprintf("Username must be between %d-%d characters long", ACCOUNT_USERNAME_LENGTH[0], ACCOUNT_USERNAME_LENGTH[1]));
- exit;
- }
-
- if (!preg_match(ACCOUNT_USERNAME_REGEX, $username)) {
- generate_alert("/account/register.php", "Bad username");
- exit;
- }
-
- $password = $_POST["password"];
- if (ACCOUNT_PASSWORD_MIN_LENGTH > strlen($password)) {
- generate_alert("/account/register.php", "Password must be at least " . ACCOUNT_PASSWORD_MIN_LENGTH . " characters");
- exit;
- }
-
- $db = new PDO(DB_URL, DB_USER, DB_PASS);
-
- $stmt = $db->prepare("SELECT id FROM users WHERE username = ?");
- $stmt->execute([$username]);
-
- if ($stmt->rowCount() != 0) {
- generate_alert("/account/register.php", "The username has already been taken");
- exit;
- }
-
- $secret_key = generate_random_string(ACCOUNT_SECRET_KEY_LENGTH);
- $password = password_hash($password, PASSWORD_DEFAULT);
-
- $id = bin2hex(random_bytes(16));
-
- $stmt = $db->prepare("INSERT INTO users(id, username, password, secret_key) VALUES (?, ?, ?, ?)");
- $stmt->execute([$id, $username, $password, $secret_key]);
-
- setcookie("secret_key", $secret_key, time() + ACCOUNT_COOKIE_MAX_LIFETIME, "/");
- header("Location: /account");
- exit;
-}
-?>
-
-<html>
-
-<head>
- <title>Register an account - <?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar(); ?>
-
- <section class="content" style="width: 400px;">
- <?php display_alert() ?>
- <section class="box">
- <div class="box navtab">
- <p>Register an account in <?php echo INSTANCE_NAME ?></p>
- </div>
- <div class="box content">
- <form action="/account/register.php" method="post">
- <div>
- <label for="username">Username</label>
- <input type="text" name="username" id="form-username" required>
- </div>
- <div>
- <label for="password">Password</label>
- <input type="password" name="password" id="form-password" required>
- </div>
- <div>
- <button type="submit">Register</button>
- </div>
- </form>
- <p style="font-size: 12px;">
- Since <?php echo INSTANCE_NAME ?> doesn't require email and password reset via email is
- not supported, please remember your passwords!
- </p>
- </div>
- </section>
- </section>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/account/security.php b/public/account/security.php
deleted file mode 100644
index 5545b60..0000000
--- a/public/account/security.php
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-
-include_once "../../src/accounts.php";
-include_once "../../src/alert.php";
-include_once "../../src/config.php";
-include_once "../../src/utils.php";
-
-if ($_SERVER["REQUEST_METHOD"] != "POST" || !authorize_user(true)) {
- header("Location: /account");
- exit;
-}
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
-$stmt->execute([$_SESSION["user_id"]]);
-
-$user = $stmt->fetch();
-$current_password = $_POST["password-current"] ?? "";
-
-if ($user["password"] != null && !password_verify($current_password, $user["password"])) {
- generate_alert("/account", "Password is required to apply changes in 'Security' section");
- exit;
-}
-
-if (!empty($_POST["password-new"])) {
- $password = $_POST["password-new"];
- if (ACCOUNT_PASSWORD_MIN_LENGTH > strlen($password)) {
- generate_alert("/account", "Your password must be at least " . ACCOUNT_PASSWORD_MIN_LENGTH . " characters");
- exit;
- }
-
- $db->prepare("UPDATE users SET password = ? WHERE id = ?")
- ->execute([password_hash($password, PASSWORD_DEFAULT), $user["id"]]);
-}
-
-$private_profile = (int) (intval($_POST["make-private"] ?? "0") == 1);
-
-$db->prepare("UPDATE user_preferences SET private_profile = ? WHERE id = ?")
- ->execute([$private_profile, $user["id"]]);
-
-if (intval($_POST["signout-everywhere"] ?? "0") == 1) {
- $db->prepare("UPDATE users SET secret_key = ? WHERE id = ?")
- ->execute([generate_random_string(ACCOUNT_SECRET_KEY_LENGTH), $_SESSION["user_id"]]);
-
- session_unset();
- session_destroy();
-
- setcookie("secret_key", "", time() - 1000);
-}
-
-generate_alert("/account", "Your changes have been applied!", 200); \ No newline at end of file
diff --git a/public/account/signout.php b/public/account/signout.php
deleted file mode 100644
index f971d4a..0000000
--- a/public/account/signout.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-include_once $_SERVER["DOCUMENT_ROOT"] . '/../src/accounts.php';
-include_once $_SERVER["DOCUMENT_ROOT"] . '/../src/alert.php';
-
-if (!isset($_GET["local"])) {
- header("Location: /");
- exit;
-}
-
-session_start();
-
-setcookie("secret_key", "", time() - 1000, "/");
-session_unset();
-session_destroy();
-
-generate_alert("/", "Signed out!", 200); \ No newline at end of file
diff --git a/public/badges.php b/public/badges.php
deleted file mode 100644
index c4444b1..0000000
--- a/public/badges.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-include_once "../src/utils.php";
-include_once "../src/config.php";
-include_once "../src/user.php";
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-$stmt = $db->prepare("SELECT
- u.id, u.username,
- r.name AS role_name,
- r.badge_id AS role_badge_id,
- ub.badge_id AS custom_badge_id,
- co.alias_id AS connection_alias_id,
- co.platform AS connection_platform
- FROM users u
- JOIN role_assigns ra ON ra.user_id = u.id
- JOIN roles r ON r.id = ra.role_id
- LEFT JOIN user_badges ub ON ub.user_id = u.id
- LEFT JOIN connections co ON co.user_id = u.id
- WHERE r.badge_id IS NOT NULL OR ub.badge_id IS NOT NULL
-");
-$stmt->execute();
-
-$rows = $stmt->fetchAll();
-
-$badges = [];
-
-foreach ($rows as $row) {
- $badge = [
- "id" => $row["id"],
- "username" => $row["username"],
- "role" => Role::from_array($row),
- "custom_badge" => Badge::from_array($row, "custom"),
- "connection" => match (isset($row["connection_alias_id"], $row["connection_platform"])) {
- true => [
- "alias_id" => $row["connection_alias_id"],
- "platform" => $row["connection_platform"]
- ],
- false => null
- }
- ];
-
- array_push($badges, $badge);
-}
-
-json_response([
- "status_code" => 200,
- "message" => null,
- "data" => $badges
-]); \ No newline at end of file
diff --git a/public/captcha.php b/public/captcha.php
deleted file mode 100644
index b454b7d..0000000
--- a/public/captcha.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-include_once "../src/config.php";
-include_once "../src/alert.php";
-include_once "../src/captcha.php";
-include_once "../src/utils.php";
-
-session_start();
-
-if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST["answer"])) {
- if ($_POST["answer"] == ($_SESSION["captcha_word"] ?? "")) {
- $_SESSION["captcha_solved"] = true;
- echo json_response([
- "status_code" => 200,
- "message" => "Solved!",
- "data" => null
- ]);
- } else {
- echo json_response([
- "status_code" => 400,
- "message" => "Wrong answer!",
- "data" => null
- ], 400);
- }
- exit;
-}
-
-$file_folder = $_SERVER["DOCUMENT_ROOT"] . '/static/img/captcha';
-
-if (!CAPTCHA_ENABLE || ($_SESSION["captcha_solved"] ?? false) || !is_dir($file_folder)) {
- $_SESSION["captcha_solved"] = true;
- echo json_response([
- "status_code" => 200,
- "message" => "No need to solve captcha",
- "data" => null
- ]);
- exit;
-}
-
-$files = scandir($file_folder);
-array_splice($files, 0, 2);
-
-$filename = $files[random_int(0, count($files) - 1)];
-$filename = basename($filename, ".png");
-
-$_SESSION["captcha_word"] = $filename;
-
-$image = generate_image_captcha(
- CAPTCHA_SIZE[0],
- CAPTCHA_SIZE[1],
- random_int(1, 3),
- $filename,
- $file_folder
-);
-
-echo json_response([
- "status_code" => 200,
- "message" => null,
- "data" => $image
-]); \ No newline at end of file
diff --git a/public/emotes/delete.php b/public/emotes/delete.php
deleted file mode 100644
index 6252e45..0000000
--- a/public/emotes/delete.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-include_once "../../src/alert.php";
-include_once "../../src/config.php";
-include_once "../../src/accounts.php";
-
-if (!authorize_user(true)) {
- generate_alert("/account", "Not authorized", 403);
- exit;
-}
-
-if (!isset($_POST["id"])) {
- generate_alert("/emotes", "Emote ID is not specified");
- exit;
-}
-
-$emote_id = $_POST["id"];
-$user_id = $_SESSION["user_id"];
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-$stmt = $db->prepare("SELECT uploaded_by, code FROM emotes WHERE id = ?");
-$stmt->execute([$emote_id]);
-
-if ($row = $stmt->fetch()) {
- if ($row["uploaded_by"] === $user_id) {
- $unlink = intval($_POST["unlink"] ?? "0") == 1;
-
- if ($unlink) {
- $stmt = $db->prepare("UPDATE emotes SET uploaded_by = NULL WHERE id = ? AND uploaded_by = ?");
- $stmt->execute([$emote_id, $user_id]);
- generate_alert("/emotes/?id=$emote_id", 'Your authorship has been removed for the emote "' . $row["code"] . '"', 200);
- } else {
- $stmt = $db->prepare("DELETE FROM emotes WHERE id = ? AND uploaded_by = ?");
- $stmt->execute([$emote_id, $user_id]);
-
- $path = $_SERVER["DOCUMENT_ROOT"] . "/static/userdata/emotes/$emote_id";
- array_map("unlink", glob("$path/*.*"));
- rmdir($path);
-
- generate_alert("/emotes", 'Emote "' . $row["code"] . '" has been removed from the servers', 200);
- }
- } else {
- generate_alert("/emotes", "You don't own the emote \"" . $row["code"] . "\"", 403);
- }
-} else {
- generate_alert("/emotes", "Emote ID $emote_id not found", 404);
-} \ No newline at end of file
diff --git a/public/emotes/index.php b/public/emotes/index.php
deleted file mode 100644
index af14120..0000000
--- a/public/emotes/index.php
+++ /dev/null
@@ -1,546 +0,0 @@
-<?php
-include "../../src/emote.php";
-include "../../src/accounts.php";
-include_once "../../src/config.php";
-include "../../src/partials.php";
-include "../../src/utils.php";
-include "../../src/alert.php";
-
-authorize_user();
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-$user_id = $_SESSION["user_id"] ?? "";
-
-$emotes = null;
-$emote = null;
-$total_emotes = 0;
-$total_pages = 0;
-
-// fetching emote by id
-if (isset($_GET["id"])) {
- $id = $_GET["id"];
-
- $stmt = $db->prepare("SELECT e.id, e.code, e.created_at, e.source, e.visibility,
- COALESCE(COUNT(r.rate), 0) as total_rating,
- COALESCE(ROUND(AVG(r.rate), 2), 0) AS average_rating,
- CASE WHEN up.private_profile = FALSE OR up.id = ? THEN e.uploaded_by ELSE NULL END AS uploaded_by
- FROM emotes e
- LEFT JOIN user_preferences up ON up.id = e.uploaded_by
- LEFT JOIN ratings AS r ON r.emote_id = e.id
- WHERE e.id = ?
- LIMIT 1
- ");
- $stmt->execute([$user_id, $id]);
-
- $row = $stmt->fetch();
-
- if ($row["id"]) {
- // fetching emote tags
- $stmt = $db->prepare("SELECT t.code FROM tags t
- INNER JOIN tag_assigns ta ON ta.emote_id = ?
- WHERE t.id = ta.tag_id
- ");
- $stmt->execute([$row["id"]]);
- $tags = $stmt->fetchAll(PDO::FETCH_ASSOC);
- $tags = array_column($tags, "code");
-
- $row["tags"] = $tags;
- $row["ext"] = "webp";
- $emote = Emote::from_array_with_user($row, $db);
- } else {
- generate_alert("/404.php", "Emote ID $id does not exists", 404);
- exit;
- }
-}
-// fetching all emotes
-else {
- $sort = $_GET["sort"] ?? "high_ratings";
- $sort = match ($sort) {
- "low_ratings" => "rating ASC",
- "recent" => "e.created_at DESC",
- "oldest" => "e.created_at ASC",
- default => "rating DESC"
- };
- $page = max(1, intval($_GET["p"] ?? "1"));
- $limit = 50;
- $offset = ($page - 1) * $limit;
- $search = $_GET["q"] ?? "";
-
- // fetching emotes
- $stmt = $db->prepare("SELECT e.*,
- CASE WHEN up.private_profile = FALSE OR up.id = ? THEN e.uploaded_by ELSE NULL END AS uploaded_by,
- CASE WHEN EXISTS (
- SELECT 1
- FROM emote_set_contents ec
- INNER JOIN emote_sets es ON es.id = ec.emote_set_id
- JOIN acquired_emote_sets aes ON aes.emote_set_id = es.id
- WHERE ec.emote_id = e.id AND es.id = ?
- ) THEN 1 ELSE 0 END AS is_in_user_set, COALESCE(COUNT(r.rate), 0) AS rating
- FROM emotes e
- LEFT JOIN user_preferences up ON up.id = e.uploaded_by
- LEFT JOIN ratings AS r ON r.emote_id = e.id
- LEFT JOIN tag_assigns ta ON ta.emote_id = e.id
- LEFT JOIN tags t ON t.id = ta.tag_id
- WHERE (t.code = ? OR e.code LIKE ?) AND e.visibility = 1
- GROUP BY
- e.id, e.code, e.created_at
- ORDER BY $sort
- LIMIT ? OFFSET ?
- ");
-
- $sql_search = "%$search%";
- $user_emote_set_id = $_SESSION["user_active_emote_set_id"] ?? "";
-
- $stmt->bindParam(1, $user_id, PDO::PARAM_STR);
- $stmt->bindParam(2, $user_emote_set_id, PDO::PARAM_STR);
- $stmt->bindParam(3, $search, PDO::PARAM_STR);
- $stmt->bindParam(4, $sql_search, PDO::PARAM_STR);
- $stmt->bindParam(5, $limit, PDO::PARAM_INT);
- $stmt->bindParam(6, $offset, PDO::PARAM_INT);
-
- $stmt->execute();
-
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
- $emotes = [];
-
- foreach ($rows as $row) {
- array_push($emotes, Emote::from_array_with_user($row, $db));
- }
-
- $total_emotes = count($emotes);
- $total_pages = ceil($total_emotes / $limit);
-}
-
-if (CLIENT_REQUIRES_JSON) {
- json_response([
- "status_code" => 200,
- "message" => null,
- "data" => $emotes ?? $emote
- ]);
- exit;
-}
-?>
-
-<html>
-
-<head>
- <title><?php
- echo ($emote != null ? "Emote " . $emote->get_code() : "Emotes") . ' - ' . INSTANCE_NAME
- ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
-
- <section class="content row">
- <section class="sidebar">
- <?php
- html_navigation_search();
- html_featured_emote($db);
- html_random_emote($db);
- ?>
- </section>
- <section class="content">
- <?php display_alert() ?>
- <section class="box">
- <div class="box navtab row">
- <?php
- if ($emote != null) {
- echo "Emote - " . $emote->get_code();
- echo '<div class="row small-gap" style="margin-left:auto">';
-
- $original_path = "/static/userdata/emotes/" . $emote->get_id();
- $files = glob($_SERVER["DOCUMENT_ROOT"] . $original_path . "/original.*");
-
- if (!empty($files)) {
- $filename = basename($files[0]);
- echo "<a href='$original_path/$filename' target='_BLANK'><img src='/static/img/icons/emotes/emote.png' alt='[Show original]' title='Show original' /></a>";
- }
-
- $stmt = $db->prepare("
- SELECT MAX(es.is_featured) AS is_featured, MAX(es.is_global) AS is_global
- FROM emote_sets es
- JOIN emote_set_contents esc ON esc.emote_set_id = es.id
- JOIN emotes e ON esc.emote_id = e.id
- WHERE e.id = ?
- ");
- $stmt->execute([$emote->get_id()]);
-
- if ($row = $stmt->fetch()) {
- if ($row["is_featured"]) {
- echo '<img src="/static/img/icons/star.png" title="Featured emote" alt="Featured" />';
- }
- if ($row["is_global"]) {
- echo '<img src="/static/img/icons/world.png" title="Global emote" alt="Global" />';
- }
- }
- echo '</div>';
- } else {
- echo "<div class='grow'>Emotes - Page $page/$total_pages</div>";
- html_emotelist_mode();
- }
- ?>
- </div>
- <?php
- if ($emote != null) { ?>
- <div class="box content">
- <div class="emote-showcase items-bottom">
- <?php
- for ($size = 1; $size < 4; $size++) {
- echo '<div class="column items-center small-gap">';
-
- echo '<img src="/static/userdata/emotes/';
- echo $emote->get_id();
- echo "/{$size}x.webp\"";
- echo 'title="' . $emote->get_code() . '" />';
-
- $path = $_SERVER["DOCUMENT_ROOT"] . '/static/userdata/emotes/' . $emote->get_id() . "/{$size}x.webp";
-
- echo '<div class="column items-center">';
-
- if ($file_size = filesize($path)) {
- $kb = sprintf("%.2f", $file_size / 1024);
- echo "<p class='font-small'>{$kb}KB</p>";
- }
-
- if ($image_size = getimagesize($path)) {
- echo "<p class='font-small'>$image_size[0]x$image_size[1]</p>";
- }
-
- echo '</div></div>';
- }
- ?>
- </div>
- </div>
- </section>
- <section class="box items row">
- <?php if (isset($_SESSION["user_id"])) {
- echo '' ?>
- <div class="items row left full">
- <?php
- $added = false;
-
- if (isset($_SESSION["user_active_emote_set_id"])) {
- $stmt = $db->prepare("SELECT id, code FROM emote_set_contents WHERE emote_set_id = ? AND emote_id = ?");
- $stmt->execute([$_SESSION["user_active_emote_set_id"], $emote->get_id()]);
-
- $added = false;
-
- if ($row = $stmt->fetch()) {
- $added = true;
- $emote_current_name = $row["code"] ?? $emote->get_code();
- }
- }
-
- if (isset($_SESSION["user_role"]) && $_SESSION["user_role"]["permission_emoteset_own"]) {
- echo '' ?>
- <form action="/emotes/setmanip.php" method="POST">
- <input type="text" name="id" value="<?php echo $emote->get_id() ?>"
- style="display: none;">
- <input type="text" name="emote_set_id"
- value="<?php echo $_SESSION["user_active_emote_set_id"] ?>" style="display: none;">
- <?php
- if ($added) {
- ?>
- <input type="text" name="action" value="remove" style="display: none;">
- <button type="submit" class="red">Remove from my channel</button>
- </form>
- <form action="/emotes/setmanip.php" method="POST" class="row">
- <input type="text" name="id" value="<?php echo $emote->get_id() ?>"
- style="display: none;">
- <input type="text" name="emote_set_id"
- value="<?php echo $_SESSION["user_active_emote_set_id"] ?>" style="display: none;">
- <input type="text" name="value" id="emote-alias-input"
- value="<?php echo $emote_current_name ?>"
- placeholder="<?php echo $emote->get_code() ?>">
- <input type="text" name="action" value="alias" style="display: none;">
- <button type="submit" class="transparent"><img src="/static/img/icons/pencil.png"
- alt="Rename" title="Rename"></button>
- <?php
- } else { ?>
- <input type="text" name="action" value="add" style="display: none;">
- <button type="submit" class="green">Add to my channel</button>
- <?php
- }
- ?>
- </form>
- <?php
- ;
- }
- ?>
-
- <?php if ($emote->get_uploaded_by() === $_SESSION["user_id"]): ?>
- <form action="/emotes/delete.php" method="post">
- <input type="text" name="id" value="<?php echo $emote->get_id() ?>"
- style="display: none;">
- <button type="submit" class="transparent">
- <img src="/static/img/icons/bin.png" alt="Delete emote" title="Delete emote">
- </button>
- </form>
- <form action="/emotes/delete.php" method="post">
- <input type="text" name="id" value="<?php echo $emote->get_id() ?>"
- style="display: none;">
- <input type="text" name="unlink" value="1" style="display:none">
- <button type="submit" class="transparent">
- <img src="/static/img/icons/link_break.png" alt="Remove your authorship"
- title="Remove your authorship">
- </button>
- </form>
- <?php endif; ?>
- </div>
- <div class="items row right full">
- <?php
- if (isset($_SESSION["user_role"])) {
- if ($_SESSION["user_role"]["permission_rate"]) {
- $stmt = $db->prepare("SELECT rate FROM ratings WHERE user_id = ? AND emote_id = ?");
- $stmt->execute([$_SESSION["user_id"], $id]);
-
- if ($row = $stmt->fetch()) {
- echo 'You gave <img src="/static/img/icons/ratings/' . $row["rate"] . '.png" width="16" height="16"';
- echo 'title="' . RATING_NAMES[$row["rate"]] . '">';
- } else {
- foreach (RATING_NAMES as $key => $value) {
- echo '<form action="/emotes/rate.php" method="POST">';
- echo '<input type="text" name="id" value="' . $emote->get_id() . '"style="display: none;">';
- echo "<input type=\"text\" name=\"rate\" value=\"$key\" style=\"display:none;\">";
- echo '<button type="submit" class="transparent">';
- echo "<img
- src=\"/static/img/icons/ratings/$key.png\" alt=\"$value!\"
- title=\"IT'S A $value!\">";
- echo '</button></form>';
- }
- }
- }
- if (REPORTS_ENABLE && $_SESSION["user_role"]["permission_report"]) {
- echo "<a class='button red' href='/report?emote_id={$emote->id}'>Report emote</a>";
- }
- }
- ?>
- </div>
- <?php
- } else {
- echo '' ?>
- <p><a href="/account/login">Log in</a> to get additional features...</p>
- <?php
- }
- ?>
- </section>
-
- <section class="box">
- <table class="vertical">
- <?php if (!empty($emote->get_tags())): ?>
- <tr>
- <th>Tags</th>
- <td>
- <?php
- foreach ($emote->get_tags() as $tag) {
- echo "<a href='/emotes/?q=$tag'>$tag</a> ";
- }
- ?>
- </td>
- </tr>
- <?php endif; ?>
- <tr>
- <th>Uploader</th>
- <td><?php
- $username = ANONYMOUS_DEFAULT_NAME;
- $link = "#";
- $show_private_badge = false;
- $badge = null;
- $custom_badge = null;
-
- if ($emote->get_uploaded_by()) {
- $u = $emote->get_uploaded_by();
- $show_private_badge = $u->private_profile;
-
- $username = $u->username;
- $link = "/users.php?id={$u->id}";
- $badge = $u->role;
- $custom_badge = $u->custom_badge;
- }
-
- echo "<a href=\"$link\">";
- echo $username;
- echo "</a>";
-
- if ($show_private_badge) {
- echo " <img src='/static/img/icons/eye.png' alt='(Private)' title='You are the only one who sees this' />";
- }
-
- if ($badge && $badge->badge) {
- echo " <img src='/static/userdata/badges/{$badge->badge->id}/1x.webp' alt='## {$badge->name}' title='{$badge->name}' />";
- }
-
- if ($custom_badge) {
- echo " <img src='/static/userdata/badges/{$custom_badge->id}/1x.webp' alt='' title='Personal badge' />";
- }
-
- echo ', <span title="';
- echo date("M d, Y H:i:s", $emote->get_created_at());
- echo ' UTC">about ' . format_timestamp(time() - $emote->get_created_at()) . " ago</span>";
- ?></td>
- </tr>
- <?php
- $stmt = $db->prepare("SELECT u.id, a.created_at FROM users u
- INNER JOIN mod_actions a ON a.emote_id = ?
- WHERE u.id = a.user_id");
- $stmt->execute([$emote->get_id()]);
-
- if ($row = $stmt->fetch()) {
- $approver = User::get_user_by_id($db, $row["id"]);
-
- echo '<tr><th>Approver</th><td>';
- echo "<a href='/users.php?id={$approver->id}' target='_blank'>{$approver->username}</a>";
-
- if ($approver->role && $approver->role->badge) {
- echo " <img src='/static/userdata/badges/{$approver->role->badge->id}/1x.webp' alt='## {$approver->role->name}' title='{$approver->role->name}' />";
- }
-
- if ($approver->custom_badge) {
- echo " <img src='/static/userdata/badges/{$approver->custom_badge->id}/1x.webp' alt='' title='Personal badge' />";
- }
-
- echo ', <span title="';
- echo date("M d, Y H:i:s", strtotime($row["created_at"])) . ' UTC">';
- echo format_timestamp(strtotime($row["created_at"]) - $emote->get_created_at()) . ' after upload';
- echo '</span></td></tr>';
- }
-
- if (RATING_ENABLE): ?>
- <tr>
- <th>Rating</th>
- <?php
- if ($emote->get_rating()["total"] < RATING_EMOTE_MIN_VOTES) {
- echo '<td>Not rated (' . $emote->get_rating()["total"] . ')</td>';
- } else {
-
- $rating = $emote->get_rating()["average"];
-
- // TODO: make it customizable
- list($rating_classname, $rating_name) = match (true) {
- in_range($rating, 0.75, 1.0) => [
- "gemerald",
- "<img src='/static/img/icons/ratings/1.png'>
- <img src='/static/img/icons/ratings/1.png'>
- <img src='/static/img/icons/ratings/1.png'> Shiny Gemerald!
- <img src='/static/img/icons/ratings/1.png'>
- <img src='/static/img/icons/ratings/1.png'>
- <img src='/static/img/icons/ratings/1.png'>
- "
- ],
- in_range($rating, 0.25, 0.75) => ["gem", "<img src='/static/img/icons/ratings/1.png'> Gem <img src='/static/img/icons/ratings/1.png'>"],
- in_range($rating, -0.25, 0.25) => ["iron", "Iron"],
- in_range($rating, -0.75, -0.25) => ["coal", "<img src='/static/img/icons/ratings/-1.png'> Coal <img src='/static/img/icons/ratings/-1.png'>"],
- in_range($rating, -1.0, -0.75) => [
- "brimstone",
- "
- <img src='/static/img/icons/ratings/brimstone.webp'>
- <img src='/static/img/icons/ratings/-1.png'>
- <img src='/static/img/icons/ratings/brimstone.webp'>
- !!!AVOID THIS CANCER-GIVING BRIMSTONE!!!
- <img src='/static/img/icons/ratings/brimstone.webp'>
- <img src='/static/img/icons/ratings/-1.png'>
- <img src='/static/img/icons/ratings/brimstone.webp'>
- "
- ]
- };
-
- echo '<td>';
- echo "<span class=\"rating $rating_classname\">$rating_name</span>";
- echo ' (' . $emote->get_rating()["total"] . ')';
- echo '</td>';
- }
- ?>
- </tr>
- <?php endif; ?>
- <tr>
- <th>Visibility</th>
- <td><?php
- 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>
- <?php if ($emote->get_source()): ?>
- <tr>
- <th>Source</th>
- <td>
- <a href="<?php echo $emote->get_source() ?>"
- target="_blank"><?php echo $emote->get_source() ?></a>
- </td>
- </tr>
- <?php endif; ?>
- </table>
- </section>
-
- <section class="box">
- <div class="content">
- <?php
- $stmt = $db->prepare("SELECT users.id, users.username
- FROM users
- INNER JOIN emote_sets AS es ON es.owner_id = users.id
- INNER JOIN emote_set_contents AS ec ON ec.emote_set_id = es.id
- INNER JOIN acquired_emote_sets AS aes ON aes.emote_set_id = es.id
- WHERE ec.emote_id = ? AND aes.is_default = TRUE");
-
- $stmt->execute([$emote->get_id()]);
- $count = $stmt->rowCount();
-
- $db = null;
-
- if ($count > 0) {
- echo "<p>Added in $count channels</p>";
- } else {
- echo "No one has added this emote yet... :'(";
- }
- ?>
- <div class="items row">
- <?php
- while ($row = $stmt->fetch()) {
- echo '<a href="/users.php?id=' . $row["id"] . '">' . $row["username"] . '</a>';
- }
- ?>
- </div>
- </div>
- <?php
- } else { ?>
- <div class="box content items">
- <?php html_display_emotes($emotes); ?>
- </div>
- <?php if ($total_pages > 1) {
- echo '' ?>
- </section>
- <section class="box center row">
- <?php
- html_pagination(
- $total_pages,
- $page,
- "/emotes?q=" . substr($search, 1, strlen($search) - 2) . "&sort_by=$sort_by"
- );
- }
- }
- ?>
- </section>
- </section>
- </section>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/emotes/rate.php b/public/emotes/rate.php
deleted file mode 100644
index 1e8eb67..0000000
--- a/public/emotes/rate.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-include_once "../../src/alert.php";
-include_once "../../src/utils.php";
-include_once "../../src/config.php";
-include_once "../../src/accounts.php";
-
-if (!RATING_ENABLE) {
- generate_alert("/404.php", "Emote ratings are disabled", 403);
- exit;
-}
-
-if (!authorize_user(true)) {
- exit;
-}
-
-if (isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_rate"]) {
- generate_alert("/404.php", "Not enough permissions", 403);
- exit;
-}
-
-$id = str_safe($_POST["id"] ?? "0", 32);
-$rate = intval(str_safe($_POST["rate"] ?? "0", 2));
-
-if ($id == 0 || $rate == 0) {
- generate_alert("/emotes" . (isset($_POST["id"]) ? "?id=" . $_POST["id"] : ""), "Not enough POST fields");
- exit;
-}
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-// checking if emote exists
-$stmt = $db->prepare("SELECT id FROM emotes WHERE id = ?");
-$stmt->execute([$id]);
-if ($stmt->rowCount() != 1) {
- generate_alert("/emotes", "Emote ID $id does not exist", 404);
- exit;
-}
-
-// checking if user has already given a rate
-$stmt = $db->prepare("SELECT id FROM ratings WHERE user_id = ? AND emote_id = ?");
-$stmt->execute([$_SESSION["user_id"], $id]);
-if ($stmt->rowCount() != 0) {
- generate_alert("/emotes?id=$id", "You have already given a rate for this emote!", 403);
- exit;
-}
-
-// giving a rate
-$stmt = $db->prepare("INSERT INTO ratings(user_id, emote_id, rate) VALUES (?, ?, ?)");
-$stmt->execute([$_SESSION["user_id"], $id, clamp($rate, -2, 2)]);
-
-if (CLIENT_REQUIRES_JSON) {
- $stmt = $db->prepare("SELECT * FROM ratings WHERE id = ?");
- $stmt->execute([$db->lastInsertId()]);
-
- json_response([
- "status_code" => 200,
- "message" => "Rated!",
- "data" => $stmt->fetch(PDO::FETCH_ASSOC)
- ]);
- exit;
-}
-
-generate_alert("/emotes?id=$id", "Rated!", 200);
diff --git a/public/emotes/setmanip.php b/public/emotes/setmanip.php
deleted file mode 100644
index 129790d..0000000
--- a/public/emotes/setmanip.php
+++ /dev/null
@@ -1,138 +0,0 @@
-<?php
-include_once "../../src/config.php";
-include "../../src/accounts.php";
-include "../../src/alert.php";
-include_once "../../src/utils.php";
-
-if (!authorize_user(true)) {
- return;
-}
-
-if (isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_emoteset_own"]) {
- generate_alert("/404.php", "Not enough permissions", 403);
- exit;
-}
-
-if (!isset($_POST["id"], $_POST["action"], $_POST["emote_set_id"])) {
- generate_alert("/emotes", "Not enough POST fields");
- exit;
-}
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-// checking emote
-$emote_id = $_POST["id"];
-$stmt = $db->prepare("SELECT id, code, uploaded_by, visibility, created_at FROM emotes WHERE id = ?");
-$stmt->execute([$emote_id]);
-if ($stmt->rowCount() == 0) {
- generate_alert("/emotes", "Emote not found", 404);
- exit;
-}
-$emote = $stmt->fetch(PDO::FETCH_ASSOC);
-
-$user_id = $_SESSION["user_id"];
-$emote_set_id = $_POST["emote_set_id"];
-
-// checking emote set
-$stmt = $db->prepare("SELECT id FROM acquired_emote_sets WHERE emote_set_id = ? AND user_id = ?");
-$stmt->execute([$emote_set_id, $user_id]);
-
-if ($stmt->rowCount() == 0) {
- generate_alert("/404.php", "You don't own emote set ID $emote_set_id", 403);
- exit;
-}
-
-// inserting emote
-$stmt = $db->prepare("SELECT id FROM emote_set_contents WHERE emote_set_id = ? AND emote_id = ?");
-$stmt->execute([$emote_set_id, $emote_id]);
-
-$action = $_POST["action"];
-$payload = [
- "emote" => $emote,
- "emoteset" => $_SESSION["user_active_emote_set"]
-];
-
-switch ($action) {
- case "add": {
- if ($stmt->rowCount() != 0) {
- generate_alert("/emotes?id=$emote_id", "This emote has been already added!");
- exit;
- }
-
- $stmt = $db->prepare("INSERT INTO emote_set_contents(emote_set_id, emote_id, added_by) VALUES (?, ?, ?)");
- $stmt->execute([$emote_set_id, $emote_id, $user_id]);
-
- if (ACCOUNT_LOG_ACTIONS) {
- $db->prepare("INSERT INTO actions(user_id, action_type, action_payload) VALUES (?, ?, ?)")
- ->execute([$user_id, "EMOTESET_ADD", json_encode($payload)]);
- }
-
- $db = null;
-
- generate_alert("/emotes?id=$emote_id", "This emote has been added to your set. Enjoy!", 200);
- break;
- }
- case "remove": {
- if ($row = $stmt->fetch()) {
- $stmt = $db->prepare("DELETE FROM emote_set_contents WHERE id = ?");
- $stmt->execute([$row["id"]]);
- } else {
- generate_alert("/emotes?id=$emote_id", "This emote wasn't added!");
- $db = null;
- exit;
- }
-
- if (ACCOUNT_LOG_ACTIONS) {
- $db->prepare("INSERT INTO actions(user_id, action_type, action_payload) VALUES (?, ?, ?)")
- ->execute([$user_id, "EMOTESET_REMOVE", json_encode($payload)]);
- }
-
- $db = null;
-
- generate_alert("/emotes?id=$emote_id", "This emote has been removed from your set.", 200);
- break;
- }
- case "alias": {
- if (!isset($_POST["value"])) {
- generate_alert("/emotes?id=$emote_id", "No value field");
- exit;
- }
-
- $value = str_safe($_POST["value"], EMOTE_NAME_MAX_LENGTH);
-
- $stmt = $db->prepare("SELECT esc.code AS alias_code, e.code FROM emote_set_contents esc
- INNER JOIN emotes e ON e.id = esc.emote_id
- WHERE esc.emote_set_id = ? AND esc.emote_id = ?");
- $stmt->execute([$emote_set_id, $emote_id]);
-
- if (empty($value)) {
- $value = null;
-
- if ($row = $stmt->fetch()) {
- $payload["emote"]["original_code"] = $row["alias_code"];
- $payload["emote"]["code"] = $row["code"];
- }
- } else {
- $row = $stmt->fetch();
- $payload["emote"]["original_code"] = $row["alias_code"] ?? $row["code"];
- $payload["emote"]["code"] = $value;
- }
-
- $stmt = $db->prepare("UPDATE emote_set_contents SET code = ? WHERE emote_set_id = ? AND emote_id = ?");
- $stmt->execute([$value, $emote_set_id, $emote_id]);
-
- if (ACCOUNT_LOG_ACTIONS) {
- $db->prepare("INSERT INTO actions(user_id, action_type, action_payload) VALUES (?, ?, ?)")
- ->execute([$user_id, "EMOTESET_ALIAS", json_encode($payload)]);
- }
-
- $db = null;
-
- generate_alert("/emotes?id=$emote_id", "Updated emote name!", 200);
- break;
- }
- default: {
- generate_alert("/emotes?id=$emote_id", "Unknown action");
- break;
- }
-} \ No newline at end of file
diff --git a/public/emotes/upload.php b/public/emotes/upload.php
deleted file mode 100644
index 644e4b6..0000000
--- a/public/emotes/upload.php
+++ /dev/null
@@ -1,552 +0,0 @@
-<?php
-include "../../src/accounts.php";
-include_once "../../src/config.php";
-include_once "../../src/alert.php";
-include_once "../../src/captcha.php";
-
-if (!EMOTE_UPLOAD) {
- generate_alert("/404.php", "Emote upload is disabled", 403);
- exit;
-}
-
-authorize_user();
-
-if (!ANONYMOUS_UPLOAD && isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_upload"]) {
- generate_alert("/404.php", "Not enough permissions", 403);
- exit;
-}
-
-$uploaded_by = null;
-$uploader_name = ANONYMOUS_DEFAULT_NAME;
-
-if (isset($_SESSION["user_role"]) && $_SESSION["user_role"]["permission_upload"]) {
- $uploaded_by = $_SESSION["user_id"] ?? null;
- $uploader_name = $_SESSION["user_name"] ?? ANONYMOUS_DEFAULT_NAME;
-}
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-function abort_upload(string $path, PDO $db, string $id)
-{
- $stmt = $db->prepare("DELETE FROM emotes WHERE id = ?");
- $stmt->execute([$id]);
- $db = null;
-
- array_map("unlink", glob("$path/*.*"));
- rmdir($path);
-}
-
-include "../../src/utils.php";
-include "../../src/images.php";
-
-$max_width = EMOTE_MAX_SIZE[0];
-$max_height = EMOTE_MAX_SIZE[1];
-
-if ($_SERVER['REQUEST_METHOD'] != "POST") {
- include "../../src/partials.php";
-
- echo '' ?>
- <html>
-
- <head>
- <title>Upload an emote - <?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
- </head>
-
- <body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
- <?php display_alert() ?>
-
- <section class="content row">
- <div class="column small-gap">
- <section class="box">
- <div class="box navtab">
- <div>
- <b>Upload a new emote</b>
- <p style="font-size:8px;">You can just upload, btw. Anything you want.</p>
- </div>
- </div>
- <div class="box content">
- <form action="/emotes/upload.php" method="POST" enctype="multipart/form-data">
- <h3>Image<span style="color:red;">*</span></h3>
-
- <input type="file" name="file" id="form-file" accept=".gif,.jpg,.jpeg,.png,.webp"
- required>
-
- <div id="form-manual-files" style="display:none;">
- <input type="file" name="file-1x" id="form-file-1x"
- accept=".gif,.jpg,.jpeg,.png,.webp">
- <label class="inline"
- for="file-1x"><?php echo sprintf("%dx%d", EMOTE_MAX_SIZE[0] / 4, EMOTE_MAX_SIZE[1] / 4) ?></label>
- <input type="file" name="file-2x" id="form-file-2x"
- accept=".gif,.jpg,.jpeg,.png,.webp">
- <label class="inline"
- for="file-2x"><?php echo sprintf("%dx%d", EMOTE_MAX_SIZE[0] / 2, EMOTE_MAX_SIZE[1] / 2) ?></label>
- <input type="file" name="file-3x" id="form-file-3x"
- accept=".gif,.jpg,.jpeg,.png,.webp">
- <label class="inline"
- for="file-3x"><?php echo sprintf("%dx%d", EMOTE_MAX_SIZE[0], EMOTE_MAX_SIZE[1]) ?></label>
- </div>
-
- <div>
- <label for="manual" class="inline">Manual resize</label>
- <input type="checkbox" name="manual" value="1" onchange="display_manual_resize()">
- </div>
-
- <h3>Emote name<span style="color:red;">*</span></h3>
- <input type="text" name="code" id="code" required>
-
- <div>
- <label for="visibility" class="inline">Emote visibility: </label>
- <select name="visibility" id="form-visibility">
- <option value="1">Public</option>
- <option value="0">Unlisted</option>
- </select><br>
- <p id="form-visibility-description" style="font-size: 10px;">test</p>
- </div>
-
- <label for="notes">Approval notes</label>
- <textarea name="notes" id="form-notes"></textarea>
-
- <table class="vertical left font-weight-normal">
- <tr>
- <th>Emote source:</th>
- <td class="flex"><input class="grow" name="source" id="form-source"></input>
- </td>
- </tr>
- <?php if (TAGS_ENABLE && TAGS_MAX_COUNT != 0): ?>
- <tr>
- <th>Tags <span class="font-small" style="cursor: help;" title="<?php
- echo 'Tags are used for fast search. ';
- if (TAGS_MAX_COUNT > 0) {
- echo 'You can use ' . TAGS_MAX_COUNT . ' tags. ';
- }
- echo 'They are space-separated o algo.';
- ?>">[?]</span>:
- </th>
- <td class="flex"><input class="grow" name="tags" id="form-tags"></input></td>
- </tr>
- <?php endif; ?>
- </table>
-
- <div>
- <label for="tos" class="inline">Do you accept <a href="/rules.php"
- target="_BLANK">the
- rules</a>?<span style="color:red;">*</span></label>
- <input type="checkbox" name="tos" value="1" required>
- </div>
-
- <button type="submit" id="upload-button">Upload as
- <?php echo $uploader_name ?></button>
- </form>
- </div>
- </section>
-
- <?php
- if (CAPTCHA_ENABLE && (CAPTCHA_FORCE_USERS || !isset($_SESSION["user_id"]))) {
- html_captcha_form();
- }
- ?>
- </div>
-
- <div class="column small-gap grow" id="emote-showcase" style="display: none;">
- <!-- Emote Preview -->
- <section class="box">
- <div class="box navtab">
- Emote Preview - <span id="emote-name"><i>Empty</i></span>
- </div>
- <div class="box content">
- <div class="emote-showcase items-bottom">
- <div class="emote-image column items-center small-gap">
- <img src="" alt="" class="emote-image-1x">
- <p class="size font-small"></p>
- </div>
- <div class="emote-image column items-center small-gap">
- <img src="" alt="" class="emote-image-2x">
- <p class="size font-small"></p>
- </div>
- <div class="emote-image column items-center small-gap">
- <img src="" alt="" class="emote-image-3x">
- <p class="size font-small"></p>
- </div>
- </div>
- <p style="font-size: 12px;">The result may differ.</p>
- </div>
- </section>
-
- <!-- Chat Preview -->
- <section class="box">
- <div class="box navtab">
- Chat Preview
- </div>
- <div class="box content no-gap column chat rounded">
- <?php
- $stmt = $db->query("SELECT u.username,
- CASE
- WHEN ub.badge_id IS NOT NULL THEN ub.badge_id
- WHEN r.badge_id IS NOT NULL THEN r.badge_id
- ELSE NULL
- END AS badge_id
- FROM users u
- LEFT JOIN user_badges ub ON ub.user_id = u.id
- LEFT JOIN role_assigns ra ON ra.user_id = u.id
- LEFT JOIN roles r ON r.id = ra.role_id
- ORDER BY RAND() LIMIT 3
- ");
-
- while ($row = $stmt->fetch()) {
- echo '<div class="row small-gap items-center chat-message">';
-
- if ($row["badge_id"]) {
- echo '<img src="/static/userdata/badges/' . $row["badge_id"] . '/1x.webp" alt="" title="" /> ';
- }
-
- echo '<span style="color: rgb(' . random_int(128, 255) . ', ' . random_int(128, 255) . ', ' . random_int(128, 255) . ')">';
- echo $row["username"];
- echo ': </span>';
-
- echo '<img src="" alt="" class="emote-image-1x">';
-
- echo '</div>';
- }
- ?>
- </div>
- </section>
- </div>
- </section>
- </div>
- </div>
- </body>
-
- <script>
- const max_width = <?php echo EMOTE_MAX_SIZE[0] ?>;
- const max_height = <?php echo EMOTE_MAX_SIZE[1] ?>;
-
- const fileInput = document.getElementById("form-file");
- const showcase = document.getElementById("emote-showcase");
- const reader = new FileReader();
-
- let manual = false;
-
- fileInput.addEventListener("change", (e) => {
- if (manual) return;
-
- showcase.style.display = "flex";
- reader.readAsDataURL(e.target.files[0]);
- reader.onload = (e) => {
- const image = new Image();
- image.src = e.target.result;
- image.onload = () => {
- let m = 1;
-
- for (let i = 3; i > 0; i--) {
- place_image(i, m, e, image);
- m *= 2;
- }
- };
- };
- });
-
- const code = document.getElementById("code");
-
- code.addEventListener("input", (e) => {
- const regex = <?php echo EMOTE_NAME_REGEX ?>;
-
- if (regex.test(e.target.value) && e.target.value.length <= <?php echo EMOTE_NAME_MAX_LENGTH ?>) {
- validCode = e.target.value;
- } else {
- e.target.value = validCode;
- }
-
- document.getElementById("emote-name").innerHTML = e.target.value ? e.target.value : "<i>Empty</i>";
- });
-
- const visibility = document.getElementById("form-visibility");
- visibility.addEventListener("change", (e) => {
- set_form_visibility_description(visibility.value);
- });
-
- function set_form_visibility_description(visibility) {
- const p = document.getElementById("form-visibility-description");
-
- if (visibility == 1) {
- p.innerHTML = "Emote won't appear on the public list until it passes a moderator's review. It still can be added to chats.";
- } else {
- p.innerHTML = "Emote doesn't appear on the public list and won't be subject to moderation checks. It still can be added to chats.";
- }
- }
-
- set_form_visibility_description(visibility.value);
-
- // Manual resize
- function display_manual_resize() {
- const manual_files = document.getElementById("form-manual-files");
-
- // resetting previous values
- const files = document.querySelectorAll("input[type=file]");
-
- for (let file of files) {
- file.value = null;
- file.removeAttribute("required");
- }
-
- const fileImages = document.querySelectorAll(".emote-image img");
-
- for (let file of fileImages) {
- file.setAttribute("src", "");
- file.setAttribute("width", "0");
- file.setAttribute("height", "0");
- }
-
- const fileSizes = document.querySelectorAll(".emote-image .size");
-
- for (let file of fileImages) {
- file.innerHTML = "";
- }
-
- manual = !manual;
-
- if (manual) {
- manual_files.style.display = "block";
- fileInput.style.display = "none";
- const elements = document.querySelectorAll("#form-manual-files input[type=file]");
- for (let elem of elements) {
- elem.setAttribute("required", "true");
- }
- } else {
- manual_files.style.display = "none";
- fileInput.style.display = "block";
- fileInput.setAttribute("required", "true");
- }
-
- showcase.style.display = "none";
- }
-
- document.getElementById("form-file-1x").addEventListener("change", (e) => {
- showcase.style.display = "flex";
- place_image(1, 4, e, null);
- });
-
- document.getElementById("form-file-2x").addEventListener("change", (e) => {
- showcase.style.display = "flex";
- place_image(2, 2, e, null);
- });
-
- document.getElementById("form-file-3x").addEventListener("change", (e) => {
- showcase.style.display = "flex";
- place_image(3, 1, e, null);
- });
-
- function place_image(image_index, multiplier, e, image) {
- let ee = e;
-
- if (image == null) {
- reader.readAsDataURL(e.target.files[0]);
- reader.onload = (e) => {
- const image = new Image();
- image.src = e.target.result;
- image.onload = () => {
- insert_image(image_index, multiplier, e, image);
- };
- }
- } else {
- insert_image(image_index, multiplier, e, image);
- }
-
- function insert_image(i, m, e, image) {
- const max_w = max_width / multiplier;
- const max_h = max_height / multiplier;
-
- const parentId = `.emote-image-${image_index}x`;
- const imgs = document.querySelectorAll(parentId);
-
- for (const img of imgs) {
- img.setAttribute("src", e.target.result);
-
- let ratio = Math.min(max_w / image.width, max_h / image.height);
-
- img.setAttribute("width", Math.floor(image.width * ratio));
- img.setAttribute("height", Math.floor(image.height * ratio));
-
- const sizeElement = document.querySelector(`.emote-image:has(${parentId}) .size`);
- sizeElement.innerHTML = `${img.getAttribute("width")}x${img.getAttribute("height")}`;
- }
- }
- }
- </script>
-
- </html>
-
- <?php
- exit;
-}
-
-if (!CLIENT_REQUIRES_JSON && CAPTCHA_ENABLE && !isset($_SESSION["captcha_solved"])) {
- generate_alert("/404.php", "You haven't solved captcha yet.", 403);
- exit;
-}
-
-$is_manual = intval($_POST["manual"] ?? "0") == 1;
-
-if ($is_manual && !isset($_FILES["file-1x"], $_FILES["file-2x"], $_FILES["file-3x"])) {
- generate_alert("/emotes/upload.php", "No files set");
- exit;
-}
-
-if (!$is_manual && !isset($_FILES["file"])) {
- generate_alert("/emotes/upload.php", "No file set");
- exit;
-}
-
-$code = str_safe($_POST["code"] ?? "", EMOTE_NAME_MAX_LENGTH);
-
-if ($code == "" || !preg_match(EMOTE_NAME_REGEX, $code)) {
- generate_alert("/emotes/upload.php", "Invalid code");
- exit;
-}
-
-$notes = str_safe($_POST["notes"] ?? "", EMOTE_COMMENT_MAX_LENGTH);
-if (empty($notes)) {
- $notes = null;
-}
-
-$source = str_safe($_POST["source"] ?? "", null);
-if (empty($source)) {
- $source = null;
-}
-
-$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
-$id = bin2hex(random_bytes(16));
-$stmt = $db->prepare("INSERT INTO emotes(id, code, notes, source, uploaded_by, visibility) VALUES (?, ?, ?, ?, ?, ?)");
-$stmt->execute([$id, $code, $notes, $source, $uploaded_by, $visibility]);
-
-$path = "../static/userdata/emotes/$id";
-
-if (!is_dir($path)) {
- mkdir($path, 0777, true);
-}
-
-if ($is_manual) {
- $image_1x = $_FILES["file-1x"];
- $image_2x = $_FILES["file-2x"];
- $image_3x = $_FILES["file-3x"];
-
- $file_1x = does_file_meet_requirements($image_1x["tmp_name"], $max_width / 4, $max_height / 4);
- $file_2x = does_file_meet_requirements($image_2x["tmp_name"], $max_width / 2, $max_height / 2);
- $file_3x = does_file_meet_requirements($image_3x["tmp_name"], $max_width, $max_height);
-
- if (!$file_1x[0] || !$file_2x[0] || !$file_3x[0]) {
- generate_alert("/emotes/upload.php", "Files don't meet requirements");
- abort_upload($path, $db, $id);
- exit;
- }
-
- if (
- !move_uploaded_file($image_1x["tmp_name"], "$path/1x.$file_1x[1]") ||
- !move_uploaded_file($image_2x["tmp_name"], "$path/2x.$file_2x[1]") ||
- !move_uploaded_file($image_3x["tmp_name"], "$path/3x.$file_3x[1]")
- ) {
- generate_alert("/emotes/upload.php", "Failed to move the uploaded files");
- abort_upload($path, $db, $id);
- exit;
- }
-} else {
- $image = $_FILES["file"];
- // resizing the image
- if ($err = create_image_bundle($image["tmp_name"], $path, $max_width, $max_height)) {
- generate_alert("/emotes/upload.php", "Error occurred while processing images ($err)", 500);
- abort_upload($path, $db, $id);
- exit;
- }
-
- if (EMOTE_STORE_ORIGINAL) {
- $ext = get_file_extension($image["tmp_name"]) ?? "";
- move_uploaded_file($image["tmp_name"], "$path/original.$ext");
- }
-}
-
-$tags = str_safe($_POST["tags"] ?? "", null);
-$tags_processed = [];
-
-if (!empty($tags) && TAGS_ENABLE) {
- $tags = explode(" ", $tags);
-
- $count = 0;
-
- foreach ($tags as $tag) {
- if (TAGS_MAX_COUNT > 0 && $count >= TAGS_MAX_COUNT) {
- break;
- }
-
- if (!preg_match(TAGS_CODE_REGEX, $tag)) {
- continue;
- }
-
- $tag_id = null;
-
- $stmt = $db->prepare("SELECT id FROM tags WHERE code = ?");
- $stmt->execute([$tag]);
-
- if ($row = $stmt->fetch()) {
- $tag_id = $row["id"];
- } else {
- $tag_id = bin2hex(random_bytes(16));
- $db->prepare("INSERT INTO tags(id, code) VALUES (?, ?)")->execute([$tag_id, $tag]);
- }
-
- $db->prepare("INSERT INTO tag_assigns(tag_id, emote_id) VALUES (?, ?)")->execute([$tag_id, $id]);
-
- $count++;
- array_push($tags_processed, $tag);
- }
-}
-
-$emote_data = [
- "id" => $id,
- "code" => $code,
- "visibility" => $visibility,
- "uploaded_by" => match ($uploaded_by == null) {
- true => null,
- false => [
- "id" => $uploaded_by,
- "username" => $uploader_name
- ]
- },
- "notes" => $notes,
- "source" => $source,
- "tags" => $tags_processed
-];
-
-if (ACCOUNT_LOG_ACTIONS && $uploaded_by != null) {
- $db->prepare("INSERT INTO actions(user_id, action_type, action_payload) VALUES (?, ?, ?)")
- ->execute([
- $uploaded_by,
- "EMOTE_CREATE",
- json_encode([
- "emote" => $emote_data
- ])
- ]);
-}
-
-
-$db = null;
-
-if (CLIENT_REQUIRES_JSON) {
- json_response([
- "status_code" => 201,
- "message" => null,
- "data" => $emote_data
- ], 201);
- exit;
-}
-
-header("Location: /emotes?id=$id", true, 307); \ No newline at end of file
diff --git a/public/emotesets.php b/public/emotesets.php
deleted file mode 100644
index 635f4c4..0000000
--- a/public/emotesets.php
+++ /dev/null
@@ -1,164 +0,0 @@
-<?php
-include_once "../src/utils.php";
-include_once "../src/config.php";
-include_once "../src/accounts.php";
-include_once "../src/partials.php";
-include_once "../src/alert.php";
-include_once "../src/emote.php";
-
-authorize_user();
-
-$id = $_GET["id"] ?? "";
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-// searching requested emoteset
-$emote_set = null;
-
-// global emoteset
-if ($id == "global") {
- $rows = $db->query("SELECT * FROM emote_sets WHERE is_global = TRUE LIMIT 1", PDO::FETCH_ASSOC);
-
- if ($rows->rowCount()) {
- $emote_set = $rows->fetch();
- } else {
- generate_alert("/404.php", "Global emoteset is not found", 404);
- exit;
- }
-}
-// featured emoteset
-else if ($id == "featured") {
- $rows = $db->query("SELECT * FROM emote_sets WHERE is_featured = TRUE LIMIT 1", PDO::FETCH_ASSOC);
-
- if ($rows->rowCount()) {
- $emote_set = $rows->fetch();
- } else {
- generate_alert("/404.php", "Featured emoteset is not found", 404);
- exit;
- }
-}
-// connected emoteset
-else if (isset($_GET["alias_id"])) {
- $alias_id = $_GET["alias_id"];
- $platform = $_GET["platform"] ?? "twitch";
-
- $stmt = $db->prepare("SELECT es.* FROM emote_sets es
- INNER JOIN connections co ON co.alias_id = ? AND co.platform = ?
- INNER JOIN acquired_emote_sets aes ON aes.user_id = co.user_id
- WHERE aes.is_default = TRUE
- ");
- $stmt->execute([$alias_id, $platform]);
-
- if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
- $emote_set = $row;
- } else {
- generate_alert("/404.php", "Emoteset is not found for alias ID $alias_id ($platform)", 404);
- exit;
- }
-}
-// specified emoteset
-else if (!empty($id)) {
- $stmt = $db->prepare("SELECT es.* FROM emote_sets es WHERE es.id = ?");
- $stmt->execute([$id]);
-
- if ($row = $stmt->fetch()) {
- $emote_set = $row;
- } else {
- generate_alert("/404.php", "Emoteset ID $id is not found", 404);
- exit;
- }
-}
-
-$user_id = $_SESSION["user_id"] ?? "";
-$emote_sets = null;
-
-// fetching emotes
-if ($emote_set) {
- $emote_set = Emoteset::from_array_extended($emote_set, $user_id, $db);
-} elseif (!EMOTESET_PUBLIC_LIST) {
- generate_alert("/404.php", "The public list of emotesets is disabled", 403);
- exit;
-} else {
- $emote_sets = [];
- foreach ($db->query("SELECT * FROM emote_sets", PDO::FETCH_ASSOC) as $row) {
- array_push($emote_sets, Emoteset::from_array_extended($row, $user_id, $db));
- }
-}
-
-if (CLIENT_REQUIRES_JSON) {
- if ($emote_sets != null) {
- json_response([
- "status_code" => 200,
- "message" => null,
- "data" => $emote_sets
- ]);
- exit;
- } else if ($emote_set != null) {
- json_response([
- "status_code" => 200,
- "message" => null,
- "data" => $emote_set
- ]);
- exit;
- } else {
- json_response([
- "status_code" => 404,
- "message" => "Emoteset(s) not found",
- "data" => null
- ], 404);
- exit;
- }
-}
-?>
-<html>
-
-<head>
- <title>
- <?php
- $title = match ($emote_set == null) {
- true => count($emote_sets) . ' emotesets',
- false => "Emoteset - {$emote_set->name}",
- };
-
- echo "$title - " . INSTANCE_NAME;
- ?>
- </title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
- <section class="content row">
- <section class="content">
- <section class="box">
- <div class="box navtab row">
- <div class="grow">
- <?php echo $title ?>
- </div>
- <?php
- if (!empty($emote_set)) {
- html_emotelist_mode();
- }
- ?>
- </div>
- <div class="box content small-gap items">
- <?php
- if (!empty($emote_sets)) {
- html_display_emoteset($emote_sets);
- } else if (!empty($emote_set)) {
- html_display_emotes($emote_set->emotes);
- } else {
- echo 'Nothing found...';
- }
- ?>
- </section>
- </section>
- </section>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/inbox.php b/public/inbox.php
deleted file mode 100644
index f7742d1..0000000
--- a/public/inbox.php
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-include_once "../src/accounts.php";
-include_once "../src/config.php";
-include_once "../src/partials.php";
-include_once "../src/utils.php";
-
-if (!authorize_user(true)) {
- exit;
-}
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-$stmt = $db->prepare("SELECT * FROM inbox_messages WHERE recipient_id = ? ORDER BY sent_at DESC");
-$stmt->execute([$_SESSION["user_id"]]);
-
-$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
-
-$stmt = $db->prepare("UPDATE inbox_messages SET has_read = true WHERE recipient_id = ?");
-$stmt->execute([$_SESSION["user_id"]]);
-
-?>
-
-<html>
-
-<head>
- <title>Inbox - <?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
- <section class="content">
- <section class="box" style="width: 50%;">
- <section class="box navtab">
- Inbox
- </section>
- <section class="box content">
- <table>
- <tr>
- <th style="width: 16px;"></th>
- <th>Contents</th>
- <th style="min-width: 96px;"></th>
- </tr>
- <?php
- foreach ($messages as $message) {
- echo '<tr';
- if (!$message["has_read"]) {
- echo ' style="background-color: yellow;"';
- }
- echo '>';
-
- echo '<td><img src="/static/img/icons/inbox/' . $message["message_type"] . '.png"></td>';
- echo '<td>' . $message["contents"];
- echo ' <span style="font-size:12px; color: gray;">(' . format_timestamp(time() - strtotime($message["sent_at"])) . ' ago)</span>';
- echo '</td>';
-
- echo '<td style="text-align:center;">';
- if ($message["link"]) {
- echo '<a href="' . $message["link"] . '">[ View ]</a>';
- }
- echo '</td>';
-
- echo '</tr>';
- }
- ?>
- </table>
- </section>
- </section>
- </section>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/index.php b/public/index.php
deleted file mode 100644
index e0746c7..0000000
--- a/public/index.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-include_once "../src/config.php";
-include_once "../src/accounts.php";
-include_once "../src/version.php";
-
-authorize_user();
-
-?>
-<html>
-
-<head>
- <title><?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper center big-gap">
- <h1><img src="/static/img/brand/big.webp" alt="<?php echo INSTANCE_NAME; ?>"></h1>
-
- <div class="items row" style="gap:32px;">
- <a href="/emotes">Emotes</a>
-
- <?php if (EMOTESET_PUBLIC_LIST): ?>
- <a href="/emotesets.php">Emotesets</a>
- <?php endif; ?>
-
- <?php if (ACCOUNT_PUBLIC_LIST): ?>
- <a href="/users.php">Users</a>
- <?php endif; ?>
-
- <?php if (EMOTE_UPLOAD && (ANONYMOUS_UPLOAD || (isset($_SESSION["user_role"]) && $_SESSION["user_role"]["permission_upload"]))) {
- echo '<a href="/emotes/upload.php">Upload</a>';
- } ?>
- <a href="/account">Account</a>
- <a href="/software.php">Chat clients & Tools</a>
- </div>
-
- <form action="/emotes" method="get" class="row">
- <input type="text" name="q">
- <button type="submit">Search</button>
- </form>
-
- <div class="counter">
- <?php
- $db = new PDO(DB_URL, DB_USER, DB_PASS);
- $results = $db->query("SELECT COUNT(*) FROM emotes WHERE visibility = 1");
- $count = $results->fetch()[0];
-
- foreach (str_split($count) as $c) {
- echo "<img src=\"/static/img/counter/$c.png\" alt=\"\" />";
- }
- ?>
- </div>
-
- <p class="font-small">
- <?php
- // cv pasted from https://gist.github.com/eusonlito/5099936
- function size($dir)
- {
- $size = 0;
-
- foreach (glob(rtrim($dir, '/') . '/*') as $each) {
- $size += is_file($each) ? filesize($each) : size($each);
- }
-
- return $size;
- }
-
- echo "Serving $count gorillion emotes and ";
-
- echo sprintf("%.2f", size("./static/userdata") / 1024 / 1024) . 'MB of active content - Running ';
-
- echo '<a href="' . TINYEMOTES_LINK . '">';
- echo sprintf("%s v%s", TINYEMOTES_NAME, TINYEMOTES_VERSION);
- echo '</a> ';
-
- if (TINYEMOTES_COMMIT != null) {
- echo '<a href="' . sprintf("%s/tree/%s", TINYEMOTES_LINK, TINYEMOTES_COMMIT) . '">(Commit ';
- echo substr(TINYEMOTES_COMMIT, 0, 7);
- echo ')</a>';
- }
- ?>
- </p>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/report/index.php b/public/report/index.php
deleted file mode 100644
index e5014c4..0000000
--- a/public/report/index.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?php
-include_once "../../src/accounts.php";
-include_once "../../src/config.php";
-include_once "../../src/partials.php";
-include_once "../../src/utils.php";
-include_once "../../src/alert.php";
-
-if (!REPORTS_ENABLE) {
- generate_alert("/404.php", "Reports are disabled", 403);
- exit;
-}
-
-if (!authorize_user(true)) {
- exit;
-}
-
-if (isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_report"]) {
- generate_alert("/404.php", "Not enough permissions", 403);
- exit;
-}
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-$report = null;
-$report_id = $_GET["id"] ?? "";
-
-if ($report_id != "") {
- $stmt = $db->prepare("SELECT * FROM reports WHERE id = ? AND sender_id = ?");
- $stmt->execute([$report_id, $_SESSION["user_id"]]);
-
- if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
- $report = $row;
-
- if (CLIENT_REQUIRES_JSON) {
- json_response([
- "status_code" => 201,
- "message" => null,
- "data" => $report
- ], 201);
- exit;
- }
- } else {
- generate_alert("/report", "Report ID #" . $_GET["id"] . " not found or not accessable");
- exit;
- }
-}
-
-$contents = "";
-
-if ($contents == "") {
- if (isset($_GET["user_id"])) {
- $contents = "Hi! I want to report user ID #" . $_GET["user_id"] . " because...";
- } else if (isset($_GET["emote_id"])) {
- $contents = "Hi! I want to report emote ID #" . $_GET["emote_id"] . " because...";
- }
-}
-?>
-
-<html>
-
-<head>
- <title><?php echo ($report == null ? "Send a message to MODS" : "A message to MODS") . ' - ' . INSTANCE_NAME ?>
- </title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
-
- <section class="content" style="width: 25%;">
- <?php display_alert() ?>
- <section class="box">
- <div class="box navtab">
- <?php echo $report == null ? "Send a message to MODS" : "A message to MODS" ?>
- </div>
- <?php if ($report == null) {
- echo '' ?>
- <div class="box content">
- <form action="/report/send.php" method="POST">
- <textarea name="contents" style="resize: none;height:250px;" autofocus
- required><?php echo $contents; ?></textarea>
- <button type="submit">Send</button>
- </form>
- </div> <?php ;
- } else {
- echo '' ?>
- <div class="box content">
- <textarea name="contents" style="resize: none;height:250px;"
- disabled><?php echo $report["contents"]; ?></textarea>
- </div>
- </section>
- <section class="box">
- <p>Reported <?php echo format_timestamp(time() - strtotime($report["sent_at"])) ?> ago</p>
- <p>Status:
- <?php echo $report["resolved_by"] == null ? "<b style='color:red;'>Unresolved</b>" : "<b style='color:green;'>Resolved</b>" ?>
- </p>
- </section>
- <?php
- if ($report["response_message"]) {
- ?>
- <section class="box">
- <div class="box navtab">
- Response from MOD
- </div>
- <div class="box content">
- <textarea name="contents" style="resize: none;height:250px;"
- disabled><?php echo $report["response_message"]; ?></textarea>
- </div>
- </section>
- <?php
- }
- ?>
- <?php ;
- }
- ?>
- </section>
- </section>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/report/list.php b/public/report/list.php
deleted file mode 100644
index f02731a..0000000
--- a/public/report/list.php
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-include_once "../../src/accounts.php";
-include_once "../../src/config.php";
-include_once "../../src/partials.php";
-include_once "../../src/utils.php";
-include_once "../../src/alert.php";
-
-if (!REPORTS_ENABLE) {
- generate_alert("/404.php", "Reports are disabled", 403);
- exit;
-}
-
-if (!authorize_user(true)) {
- exit;
-}
-
-if (isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_report"]) {
- generate_alert("/404.php", "Not enough permissions", 403);
- exit;
-}
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-$stmt = $db->prepare("SELECT * FROM reports WHERE sender_id = ? ORDER BY sent_at DESC");
-$stmt->execute([$_SESSION["user_id"]]);
-
-$reports = $stmt->fetchAll(PDO::FETCH_ASSOC);
-?>
-
-<html>
-
-<head>
- <title>Report list - <?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
- <section class="content">
- <section class="box" style="width: 50%;">
- <section class="box navtab">
- Report list
- </section>
- <section class="box content">
- <table>
- <tr>
- <th>Contents</th>
- <th>Status</th>
- <th style="min-width: 96px;"></th>
- </tr>
- <?php
- foreach ($reports as $report) {
- echo '<tr>';
-
- echo '<td>' . substr($report["contents"], 0, 20) . "...";
- echo ' <span style="font-size:12px; color: gray;">(' . format_timestamp(time() - strtotime($report["sent_at"])) . ' ago)</span>';
- echo '</td>';
-
- echo '<td>';
- echo $report["resolved_by"] == null ? "<b style='color:red;'>Unresolved</b>" : "<b style='color:green;'>Resolved</b>";
- echo '</td>';
-
- echo '<td style="text-align:center;">';
- echo '<a href="/report?id=' . $report["id"] . '">[ View ]</a>';
- echo '</td>';
-
- echo '</tr>';
- }
- ?>
- </table>
- </section>
- </section>
- </section>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/report/send.php b/public/report/send.php
deleted file mode 100644
index ab136e1..0000000
--- a/public/report/send.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-include_once "../../src/accounts.php";
-include_once "../../src/config.php";
-include_once "../../src/utils.php";
-include_once "../../src/alert.php";
-
-if (!REPORTS_ENABLE) {
- generate_alert("/404.php", "Reports are disabled", 403);
- exit;
-}
-
-if (!authorize_user(true)) {
- exit;
-}
-
-if (isset($_SESSION["user_role"]) && !$_SESSION["user_role"]["permission_report"]) {
- generate_alert("/404.php", "Not enough permissions", 403);
- exit;
-}
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-if (!isset($_POST["contents"])) {
- generate_alert("/report", "Not enough POST fields");
- exit;
-}
-
-$stmt = $db->prepare("INSERT INTO reports(sender_id, contents) VALUES (?, ?)");
-$stmt->execute([$_SESSION["user_id"], str_safe($_POST["contents"], 200)]);
-
-$report_id = $db->lastInsertId();
-
-$stmt = $db->prepare("SELECT * FROM reports WHERE id = ?");
-$stmt->execute([$report_id]);
-
-if (CLIENT_REQUIRES_JSON) {
- json_response([
- "status_code" => 201,
- "message" => null,
- "data" => $stmt->fetch(PDO::FETCH_ASSOC)
- ], 201);
- exit;
-}
-
-generate_alert("/report?id=$report_id", "Thank you for your vigilance! MODS will take action as soon as possible.", 200);
diff --git a/public/rules.php b/public/rules.php
deleted file mode 100644
index 027b994..0000000
--- a/public/rules.php
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-include_once "../src/config.php";
-include_once "../src/partials.php";
-include_once "../src/accounts.php";
-
-authorize_user();
-
-$contents = "";
-
-$path = sprintf("%s/%s/txt/RULES", $_SERVER["DOCUMENT_ROOT"], INSTANCE_STATIC_FOLDER);
-
-if (is_file($path)) {
- $contents = file_get_contents($path);
- $contents = explode("\n", $contents);
-}
-?>
-
-<html>
-
-<head>
- <title>The Rules of <?php echo INSTANCE_NAME ?></title>
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
- <link rel="stylesheet" href="/static/style.css">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
- <div class="content row">
- <div class="sidebar" style="min-width: 300px;"></div>
- <div class="content">
- <h1>The Rules of <?php echo INSTANCE_NAME ?></h1>
- <ol>
- <?php
- foreach ($contents as $line) {
- echo "<li>$line</li>";
- }
- if (empty($contents)) {
- echo "<i>No rules!</i>";
- }
- ?>
- </ol>
- </div>
- </div>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/software.php b/public/software.php
deleted file mode 100644
index e45fd86..0000000
--- a/public/software.php
+++ /dev/null
@@ -1,83 +0,0 @@
-<?php
-include_once "../src/config.php";
-include_once "../src/partials.php";
-
-$software = [
- "Standalone clients" =>
- [
- [
- "name" => "Tinyrino",
- "author" => "ilotterytea",
- "desc" => "Tinyrino is a fork of Chatterino7 (which is a fork of Chatterino 2). This fork supports TinyEmotes, a software that allows you to host your emotes on your own instances.",
- "download_url" => "https://github.com/ilotterytea/tinyrino/releases",
- "source_url" => "https://github.com/ilotterytea/tinyrino"
- ]
- ],
- "Web extensions" => [],
- "Chatbots" => [],
- "Other tools" => []
-];
-?>
-
-<html>
-
-<head>
- <title>Software - <?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
- <section class="content">
- <?php
- foreach ($software as $software_name => $sw) {
- echo '<section class="box">';
- echo "<div class='box navtab'>$software_name</div>";
- echo '<div class="box content">';
-
- if (empty($sw)) {
- echo '<p>There are no software in this category! They will appear here as soon as they support TinyEmotes.</p>';
- }
-
- foreach ($sw as $s) {
- $name_lower = strtolower($s["name"]);
- echo '<div class="box row small-gap">';
- echo "<div><img src='/static/img/software/$name_lower/icon.png' alt=''></div>";
-
- echo '<div class="column grow small-gap">';
- echo '<div class="row"><h1>' . $s["name"] . '</h1><p style="font-size:10px;">by ' . $s["author"] . '</p></div>';
- echo '<p>' . $s["desc"] . '</p>';
-
- $screenshot_path = "./static/img/software/$name_lower/screenshots";
- if (is_dir($screenshot_path)) {
- echo '<div class="row small-gap screenshots">';
- foreach (new DirectoryIterator($screenshot_path) as $file) {
- if ($file->isDot()) {
- continue;
- }
-
- echo "<a href='$screenshot_path/$file' target='_blank'><img src='$screenshot_path/$file' alt=''></a>";
- }
- echo '</div>';
- }
-
- echo '</div>';
-
- echo '<div class="column small-gap items-center">';
- echo '<a href="' . $s["download_url"] . '" target="_blank" class="button green big">Download</a>';
- echo '<a href="' . $s["source_url"] . '" target="_blank">[ Source code ]</a>';
- echo '</div></div>';
- }
-
- echo '</div></section>';
- }
- ?>
- </section>
- </div>
- </div>
-</body>
-
-</html> \ No newline at end of file
diff --git a/public/static/favicon.ico b/public/static/favicon.ico
deleted file mode 100644
index ff8f9ad..0000000
--- a/public/static/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/public/static/img/404/1.webp b/public/static/img/404/1.webp
deleted file mode 100644
index 7fc04a8..0000000
--- a/public/static/img/404/1.webp
+++ /dev/null
Binary files differ
diff --git a/public/static/img/brand/big.webp b/public/static/img/brand/big.webp
deleted file mode 100644
index c665251..0000000
--- a/public/static/img/brand/big.webp
+++ /dev/null
Binary files differ
diff --git a/public/static/img/brand/mini.webp b/public/static/img/brand/mini.webp
deleted file mode 100644
index ce0f91f..0000000
--- a/public/static/img/brand/mini.webp
+++ /dev/null
Binary files differ
diff --git a/public/static/img/counter/0.png b/public/static/img/counter/0.png
deleted file mode 100644
index 929946c..0000000
--- a/public/static/img/counter/0.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/counter/1.png b/public/static/img/counter/1.png
deleted file mode 100644
index f1c151d..0000000
--- a/public/static/img/counter/1.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/counter/2.png b/public/static/img/counter/2.png
deleted file mode 100644
index 7a5a2af..0000000
--- a/public/static/img/counter/2.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/counter/3.png b/public/static/img/counter/3.png
deleted file mode 100644
index c7c7598..0000000
--- a/public/static/img/counter/3.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/counter/4.png b/public/static/img/counter/4.png
deleted file mode 100644
index cd5b8b9..0000000
--- a/public/static/img/counter/4.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/counter/5.png b/public/static/img/counter/5.png
deleted file mode 100644
index 3455958..0000000
--- a/public/static/img/counter/5.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/counter/6.png b/public/static/img/counter/6.png
deleted file mode 100644
index c7f795d..0000000
--- a/public/static/img/counter/6.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/counter/7.png b/public/static/img/counter/7.png
deleted file mode 100644
index 925bb68..0000000
--- a/public/static/img/counter/7.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/counter/8.png b/public/static/img/counter/8.png
deleted file mode 100644
index 7cb611e..0000000
--- a/public/static/img/counter/8.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/counter/9.png b/public/static/img/counter/9.png
deleted file mode 100644
index f8ff704..0000000
--- a/public/static/img/counter/9.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/defaults/profile_picture.png b/public/static/img/defaults/profile_picture.png
deleted file mode 100644
index caaab1a..0000000
--- a/public/static/img/defaults/profile_picture.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/bin.png b/public/static/img/icons/bin.png
deleted file mode 100644
index 375b8bf..0000000
--- a/public/static/img/icons/bin.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/clock.png b/public/static/img/icons/clock.png
deleted file mode 100644
index e2672c2..0000000
--- a/public/static/img/icons/clock.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/connect.png b/public/static/img/icons/connect.png
deleted file mode 100644
index 024138e..0000000
--- a/public/static/img/icons/connect.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/connections/twitch.webp b/public/static/img/icons/connections/twitch.webp
deleted file mode 100644
index c2882b4..0000000
--- a/public/static/img/icons/connections/twitch.webp
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/disconnect.png b/public/static/img/icons/disconnect.png
deleted file mode 100644
index b335cb1..0000000
--- a/public/static/img/icons/disconnect.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/door_in.png b/public/static/img/icons/door_in.png
deleted file mode 100644
index 41676a0..0000000
--- a/public/static/img/icons/door_in.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/door_out.png b/public/static/img/icons/door_out.png
deleted file mode 100644
index 2541d2b..0000000
--- a/public/static/img/icons/door_out.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/emotes/emote.png b/public/static/img/icons/emotes/emote.png
deleted file mode 100644
index 3cf0a16..0000000
--- a/public/static/img/icons/emotes/emote.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/emotes/emote_folder.png b/public/static/img/icons/emotes/emote_folder.png
deleted file mode 100644
index 2f8951f..0000000
--- a/public/static/img/icons/emotes/emote_folder.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/emotes/emote_go.png b/public/static/img/icons/emotes/emote_go.png
deleted file mode 100644
index 36ae3f6..0000000
--- a/public/static/img/icons/emotes/emote_go.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/emoticon_happy.png b/public/static/img/icons/emoticon_happy.png
deleted file mode 100644
index 6b7336e..0000000
--- a/public/static/img/icons/emoticon_happy.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/eye.png b/public/static/img/icons/eye.png
deleted file mode 100644
index 564a1a9..0000000
--- a/public/static/img/icons/eye.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/heart.png b/public/static/img/icons/heart.png
deleted file mode 100644
index d9ee53e..0000000
--- a/public/static/img/icons/heart.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/inbox/0.png b/public/static/img/icons/inbox/0.png
deleted file mode 100644
index c149c2b..0000000
--- a/public/static/img/icons/inbox/0.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/inbox/1.png b/public/static/img/icons/inbox/1.png
deleted file mode 100644
index 89c8129..0000000
--- a/public/static/img/icons/inbox/1.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/inbox/2.png b/public/static/img/icons/inbox/2.png
deleted file mode 100644
index 7348aed..0000000
--- a/public/static/img/icons/inbox/2.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/link_break.png b/public/static/img/icons/link_break.png
deleted file mode 100644
index 5235753..0000000
--- a/public/static/img/icons/link_break.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/new_emote.png b/public/static/img/icons/new_emote.png
deleted file mode 100644
index 82d263e..0000000
--- a/public/static/img/icons/new_emote.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/no.png b/public/static/img/icons/no.png
deleted file mode 100644
index c149c2b..0000000
--- a/public/static/img/icons/no.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/pencil.png b/public/static/img/icons/pencil.png
deleted file mode 100644
index 0bfecd5..0000000
--- a/public/static/img/icons/pencil.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/ratings/-1.png b/public/static/img/icons/ratings/-1.png
deleted file mode 100644
index 38f492a..0000000
--- a/public/static/img/icons/ratings/-1.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/ratings/1.png b/public/static/img/icons/ratings/1.png
deleted file mode 100644
index 0b01c2b..0000000
--- a/public/static/img/icons/ratings/1.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/ratings/brimstone.webp b/public/static/img/icons/ratings/brimstone.webp
deleted file mode 100644
index 98b0d62..0000000
--- a/public/static/img/icons/ratings/brimstone.webp
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/star.png b/public/static/img/icons/star.png
deleted file mode 100644
index b88c857..0000000
--- a/public/static/img/icons/star.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/table.png b/public/static/img/icons/table.png
deleted file mode 100644
index abcd936..0000000
--- a/public/static/img/icons/table.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/tag_blue.png b/public/static/img/icons/tag_blue.png
deleted file mode 100644
index 9757fc6..0000000
--- a/public/static/img/icons/tag_blue.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/user.png b/public/static/img/icons/user.png
deleted file mode 100644
index 79f35cc..0000000
--- a/public/static/img/icons/user.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/world.png b/public/static/img/icons/world.png
deleted file mode 100644
index 68f21d3..0000000
--- a/public/static/img/icons/world.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/icons/yes.png b/public/static/img/icons/yes.png
deleted file mode 100644
index 89c8129..0000000
--- a/public/static/img/icons/yes.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/software/tinyrino/icon.png b/public/static/img/software/tinyrino/icon.png
deleted file mode 100644
index 8f5bce3..0000000
--- a/public/static/img/software/tinyrino/icon.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/software/tinyrino/screenshots/1.png b/public/static/img/software/tinyrino/screenshots/1.png
deleted file mode 100644
index 8e4d993..0000000
--- a/public/static/img/software/tinyrino/screenshots/1.png
+++ /dev/null
Binary files differ
diff --git a/public/static/img/software/tinyrino/screenshots/2.png b/public/static/img/software/tinyrino/screenshots/2.png
deleted file mode 100644
index ec21185..0000000
--- a/public/static/img/software/tinyrino/screenshots/2.png
+++ /dev/null
Binary files differ
diff --git a/public/static/style.css b/public/static/style.css
deleted file mode 100644
index 9aa1ca9..0000000
--- a/public/static/style.css
+++ /dev/null
@@ -1,640 +0,0 @@
-:root {
- --background-color: #c4d1b5;
- --background-color-hover: #e4eed8;
- --background-color-disabled: #bec6b3;
- --border-color: #95a186;
-
- --background-color-2: #cfdfbd;
- --border-color-2: #849275;
-
- --foreground-color: #425514;
- --foreground-color-hover: #1c220c;
-
- --body-background: #f2f8ee;
-
- --profile-background: radial-gradient(#f2f8eebb, #f2f8ee);
-
- /** NAVBAR */
- --navbar-background: linear-gradient(0deg, #b9caaf, #eaffdd);
- --navbar-border-color: #94a58a;
-}
-
-* {
- padding: 0;
- margin: 0;
-
- font-family: Arial, Helvetica, sans-serif;
-}
-
-body {
- background: var(--body-background);
-}
-
-h1 {
- font-size: 26px;
-}
-
-h2 {
- font-size: 20px;
-}
-
-h3 {
- font-size: 16px;
-}
-
-div {
- display: unset;
-}
-
-table {
- text-align: left;
-}
-
-table.vertical th {
- text-align: right;
-}
-
-table.vertical.left th {
- text-align: left;
-}
-
-table.vertical th,
-table.vertical td {
- padding: 2px;
-}
-
-a {
- color: var(--foreground-color);
- text-decoration: none;
-}
-
-a:hover {
- color: var(--foreground-color-hover);
- text-decoration: underline;
-}
-
-input {
- padding: 2px;
- border-radius: 4px;
- border: 1px solid gray;
-}
-
-input[type=file] {
- max-width: 230px;
-}
-
-form {
- display: flex;
- flex-direction: column;
-}
-
-form:has(div) {
- gap: 16px;
-}
-
-label {
- display: block;
-}
-
-label.inline {
- display: inline;
-}
-
-textarea {
- resize: vertical;
- height: 100px;
-}
-
-.container {
- width: 100%;
- min-height: 100vh;
- display: flex;
-}
-
-.wrapper {
- flex-grow: 1;
- display: flex;
- flex-direction: column;
-}
-
-.content {
- flex-grow: 1;
- display: flex;
- flex-direction: column;
- gap: 6px;
- margin: 6px;
-}
-
-.page {
- display: flex;
- flex-direction: row;
-}
-
-.screenshots img {
- height: 128px;
-}
-
-.content.row>.content {
- margin: 0;
-}
-
-.sidebar {
- max-width: 300px;
-}
-
-/**
-------------
- COUNTER
-------------
-*/
-.counter img:not(:first-child) {
- margin-left: 32px;
-}
-
-
-/**
------------
- NAVBAR
------------
-*/
-
-.navbar {
- background: var(--navbar-background);
- border-bottom: 1px solid var(--navbar-border-color);
- display: flex;
- flex-direction: row;
- padding: 4px;
- gap: 16px;
-}
-
-.navbar .links {
- display: flex;
- align-items: end;
- gap: 4px;
-}
-
-.navbar .brand {
- display: flex;
- flex-direction: row;
- align-items: end;
-}
-
-/**
--------------
- BUTTONS
--------------
-*/
-
-button,
-.button {
- background: lightgray;
- border: 1px solid gray;
- border-radius: 4px;
- padding: 2px 4px;
- font-size: 14px;
- text-decoration: none;
- color: black;
-}
-
-button:disabled {
- color: gray;
-}
-
-button:disabled:hover {
- cursor: not-allowed;
- background: lightgray;
- color: gray;
-}
-
-button:hover,
-.button:hover {
- background: #b9b9b9;
- cursor: pointer;
- color: black;
- text-decoration: none;
-}
-
-button.transparent,
-.button.transparent {
- background: unset;
- border: unset;
-}
-
-.gem:hover {
- filter: saturate(2);
-}
-
-.coal:hover {
- filter: brightness(2);
-}
-
-button.red,
-.button.red {
- background: #e97272;
- border-color: #a85252;
-}
-
-button.red:hover,
-.button.red:hover {
- background: #ec8d8d;
-}
-
-button.green,
-.button.green {
- background: #6cbb6d;
- border-color: #52a85d;
-}
-
-button.green:hover,
-.button.green:hover {
- background: #85dd8a;
-}
-
-button.purple,
-.button.purple,
-.twitch {
- background: #9a7ad2 !important;
- border-color: #6d5595 !important;
-}
-
-button.purple:hover,
-.button.purple:hover {
- background: #ac88ea;
-}
-
-button.big,
-.button.big {
- padding: 8px 24px;
- font-size: 18px;
-}
-
-/**
-----------
- LIST
-----------
-*/
-
-.items {
- display: flex;
- flex-direction: column;
- gap: 6px;
-}
-
-.items.content {
- flex-grow: 1;
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- gap: 16px;
-}
-
-.navtab {
- position: relative;
- width: 50%;
- top: 2px;
-}
-
-.full {
- flex-grow: 1;
-}
-
-.right {
- justify-content: flex-end;
-}
-
-/**
----------
- BOX
----------
-*/
-
-.box {
- background: var(--background-color);
- border: 2px solid var(--border-color);
- border-radius: 4px;
- padding: 8px;
-}
-
-.box.navtab {
- border-bottom-left-radius: 0;
- border-bottom-right-radius: 0;
- border-bottom: unset;
- margin: 0;
-}
-
-.box:has(.navtab) {
- background: unset;
- border: unset;
- border-radius: unset;
- padding: 0;
-
- display: flex;
- flex-direction: column;
-}
-
-.box:has(.navtab) .content {
- flex-grow: 1;
- margin: 0;
- padding: 16px;
-}
-
-.box .content .box {
- background: var(--background-color-2);
- border-color: var(--border-color-2);
-}
-
-.box .content a.box:hover {
- background: linear-gradient(0deg, var(--background-color-hover), var(--background-color-2));
- cursor: pointer;
-}
-
-.box hr {
- border-color: var(--border-color);
- border-width: 1px;
-}
-
-.box.emote {
- width: 96px;
- height: 96px;
-}
-
-.box.background {
- background-size: 100% 100%;
- background-position: center;
- background-repeat: no-repeat;
- overflow: hidden;
-}
-
-.box.background h1 {
- color: white;
- text-shadow: -1px 1px 4px black;
-}
-
-.box.emote h1 {
- font-size: 16px;
- font-weight: 600;
-
- max-width: 100px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.box.emote p {
- max-width: 100px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- font-size: 10px;
-}
-
-.box.emote:has(.emote-desc) img {
- max-width: 64px;
- max-height: 64px;
-}
-
-.box.emote:has(.emote-desc.none) img {
- max-width: 96px;
- max-height: 96px;
-}
-
-a.box {
- text-decoration: none;
- color: black;
-}
-
-a.box:hover {
- background: linear-gradient(0deg, var(--background-color-hover), var(--background-color-disabled));
- cursor: pointer;
-}
-
-.emote-showcase {
- flex-grow: 1;
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 32px;
- margin: 32px 0;
-}
-
-.alert.red {
- background: #e27777;
- border-color: #9f5050;
-}
-
-.emote-check {
- position: relative;
- left: 35px;
- top: 10px;
- width: 24px;
- height: 24px;
- z-index: 2;
-}
-
-.emote:has(.emote-check) img {
- margin-top: -15px;
-}
-
-/** RATINGS */
-.rating.gemerald {
- font-weight: bolder;
- text-shadow: 0 0 5px blue;
- color: #b4dbeb;
-}
-
-.rating.gemerald img {
- filter: hue-rotate(50deg) brightness(1.5);
-}
-
-.rating.gem {
- font-weight: bold;
- color: #2e7b99;
-}
-
-.rating.coal {
- font-weight: bold;
- color: #2d3335;
- text-shadow: 0 0 2px black;
-}
-
-.rating.brimstone {
- font-weight: bolder;
- color: orange;
- text-shadow: 0 0 4px red;
-}
-
-/**
--------------
- ACCOUNTS
--------------
-*/
-
-.accman {
- flex-grow: 0;
- width: 400px;
-
- display: flex;
- flex-direction: column;
- gap: 16px;
-}
-
-.badge {
- padding: 2px 8px;
- border-radius: 4px;
- border-width: 1px;
- border-style: solid;
-}
-
-.badge img {
- max-width: 16px;
- max-height: 16px;
- vertical-align: middle;
-}
-
-/**
----------------------------------
- SOMETHING FROM TAILWINDCSS
----------------------------------
-*/
-
-.row {
- display: flex;
- flex-direction: row;
-}
-
-.column {
- display: flex;
- flex-direction: column;
-}
-
-.grow {
- flex-grow: 1;
-}
-
-.small-gap {
- gap: 8px;
-}
-
-.big-gap {
- gap: 32px;
-}
-
-.no-gap {
- gap: 0;
-}
-
-.center {
- justify-content: center;
- align-items: center;
-}
-
-.items-center {
- align-items: center;
-}
-
-.items-bottom {
- align-items: end;
-}
-
-.justify-center {
- justify-content: center;
-}
-
-.justify-between {
- justify-content: space-between;
-}
-
-.justify-bottom {
- justify-content: end;
-}
-
-.font-small {
- font-size: 12px;
-}
-
-.p-16 {
- padding: 16px;
-}
-
-.m-8 {
- margin: 8px;
-}
-
-.inline {
- display: inline;
-}
-
-.flex {
- display: flex;
-}
-
-.none {
- display: none;
-}
-
-.w-full {
- width: 100%;
-}
-
-.font-weight-normal,
-.font-weight-normal th {
- font-weight: normal;
-}
-
-.rounded {
- border-radius: 4px;
-}
-
-/**
--------------
- USER
--------------
-*/
-
-.background {
- position: absolute;
- background-position: center center;
- top: 61px;
- bottom: 0;
- left: 0;
- right: 0;
- z-index: -1;
-}
-
-.background-layer {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
- background: var(--profile-background);
-}
-
-/**
--------------
- CHAT
--------------
-*/
-
-.chat-message {
- background: linear-gradient(0deg, #202020, #303030);
- color: #fff;
- padding: 8px;
-}
-
-.chat .chat-message:nth-child(even) {
- background: linear-gradient(0deg, #353535, #454545);
-
- border-top: 1px solid #707070;
- border-bottom: 1px solid #707070;
-}
-
-.chat.rounded .chat-message:first-child {
- border-top-left-radius: 4px;
- border-top-right-radius: 4px;
-}
-
-.chat.rounded .chat-message:last-child {
- border-bottom-left-radius: 4px;
- border-bottom-right-radius: 4px;
-} \ No newline at end of file
diff --git a/public/static/txt/RULES b/public/static/txt/RULES
deleted file mode 100644
index 0ec5b9e..0000000
--- a/public/static/txt/RULES
+++ /dev/null
@@ -1,2 +0,0 @@
-Hey, admin! Write your rules in /static/txt/RULES file.
-If you see this, VI VON \ No newline at end of file
diff --git a/public/system/emotes/index.php b/public/system/emotes/index.php
deleted file mode 100644
index 2a48408..0000000
--- a/public/system/emotes/index.php
+++ /dev/null
@@ -1,250 +0,0 @@
-<?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;
-}
-
-$current_user_id = $_SESSION["user_id"] ?? "";
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-$emote_results = $db->prepare("SELECT e.*,
-CASE WHEN up.private_profile = FALSE OR up.id = ? THEN e.uploaded_by ELSE NULL END AS uploaded_by,
-CASE WHEN up.private_profile = FALSE OR up.id = ? THEN u.username ELSE NULL END AS uploader_name,
-r.name AS role_name,
-r.badge_id AS role_badge_id,
-ub.badge_id AS custom_badge_id
-FROM emotes e
-LEFT JOIN users u ON u.id = e.uploaded_by
-LEFT JOIN user_preferences up ON up.id = u.id
-LEFT JOIN role_assigns ra ON ra.user_id = u.id
-LEFT JOIN roles r ON r.id = ra.role_id
-LEFT JOIN user_badges ub ON ub.user_id = u.id
-WHERE e.visibility = 2
-ORDER BY e.created_at DESC
-LIMIT 25
-");
-$emote_results->execute([$current_user_id, $current_user_id]);
-
-$emote_results = $emote_results->fetchAll(PDO::FETCH_ASSOC);
-
-$emote = $emote_results[0] ?? null;
-
-if (isset($_GET["id"])) {
- $stmt = $db->prepare("SELECT e.*,
- CASE WHEN up.private_profile = FALSE OR up.id = ? THEN e.uploaded_by ELSE NULL END AS uploaded_by,
- CASE WHEN up.private_profile = FALSE OR up.id = ? THEN u.username ELSE NULL END AS uploader_name,
- r.name AS role_name,
- r.badge_id AS role_badge_id,
- ub.badge_id AS custom_badge_id
- FROM emotes e
- LEFT JOIN users u ON u.id = e.uploaded_by
- LEFT JOIN user_preferences up ON up.id = u.id
- LEFT JOIN role_assigns ra ON ra.user_id = u.id
- LEFT JOIN roles r ON r.id = ra.role_id
- LEFT JOIN user_badges ub ON ub.user_id = u.id
- WHERE e.visibility = 2 AND e.id = ?
- LIMIT 1");
-
- $stmt->execute([$current_user_id, $current_user_id, $_GET["id"]]);
- $emote = $stmt->fetch(PDO::FETCH_ASSOC) ?? null;
-}
-
-?>
-
-<html>
-
-<head>
- <title>System panel - <?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</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.webp">';
- 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 row">
- <?php
- echo "Emote - " . $emote["code"];
- echo '<div class="row small-gap" style="margin-left:auto">';
-
- $original_path = "/static/userdata/emotes/" . $emote["id"];
- $files = glob($_SERVER["DOCUMENT_ROOT"] . $original_path . "/original.*");
-
- if (!empty($files)) {
- $filename = basename($files[0]);
- echo "<a href='$original_path/$filename' target='_BLANK'><img src='/static/img/icons/emotes/emote.png' alt='[Show original]' title='Show original' /></a>";
- }
- echo '</div>';
- ?>
- </div>
- <div class="box content">
- <div class="emote-showcase items-bottom">
- <?php
- for ($size = 1; $size < 4; $size++) {
- echo '<div class="column items-center small-gap">';
-
- echo '<img src="/static/userdata/emotes/';
- echo $emote["id"];
- echo "/{$size}x.webp\"";
- echo 'title="' . $emote["code"] . '" />';
-
- $path = $_SERVER["DOCUMENT_ROOT"] . '/static/userdata/emotes/' . $emote["id"] . "/{$size}x.webp";
-
- echo '<div class="column items-center">';
-
- if ($file_size = filesize($path)) {
- $kb = sprintf("%.2f", $file_size / 1024);
- echo "<p class='font-small'>{$kb}KB</p>";
- }
-
- if ($image_size = getimagesize($path)) {
- echo "<p class='font-small'>$image_size[0]x$image_size[1]</p>";
- }
-
- echo '</div></div>';
- }
- ?>
- </div>
- </div>
- </section>
- <!-- Emote information -->
- <section class="box">
- <table class="vertical">
- <?php
- $stmt = $db->prepare("SELECT t.code FROM tags t
- INNER JOIN tag_assigns ta ON ta.emote_id = ?
- WHERE t.id = ta.tag_id
- ");
- $stmt->execute([$emote["id"]]);
-
- $tags = $stmt->fetchAll(PDO::FETCH_ASSOC);
- $tags = array_column($tags, "code");
-
- if (!empty($tags)) {
- echo '<tr><th>Tags</th><td>';
- foreach ($tags as $tag) {
- echo "<a href='/emotes/?q=$tag'>$tag</a> ";
- }
- echo '</td></tr>';
- }
- ?>
- <tr>
- <th>Uploader</th>
- <td><?php
- $username = ANONYMOUS_DEFAULT_NAME;
- $link = "#";
-
- if ($emote["uploader_name"] != null) {
- $username = $emote["uploader_name"];
- $link = '/users.php?id=' . $emote["uploaded_by"];
- }
-
- echo "<a href=\"$link\">";
- echo $username;
- echo "</a>";
-
- if ($emote["role_badge_id"]) {
- echo ' <img src="/static/userdata/badges/' . $emote["role_badge_id"] . '/1x.webp" alt="## ' . $emote["role_name"] . '" title="' . $emote["role_name"] . '" />';
- }
-
- if ($emote["custom_badge_id"]) {
- echo ' <img src="/static/userdata/badges/' . $emote["custom_badge_id"] . '/1x.webp" alt="" title="Personal badge" />';
- }
-
- echo ', <span title="';
- echo date("M d, Y H:i:s", strtotime($emote["created_at"]));
- echo ' UTC">about ' . format_timestamp(time() - strtotime($emote["created_at"])) . " ago</span>";
- ?></td>
- </tr>
- <tr>
- <th>Notes</th>
- <td><?php echo isset($emote["notes"]) == true ? $emote["notes"] : '<i>Empty</i>' ?></td>
- </tr>
- <?php if ($emote["source"]): ?>
- <tr>
- <th>Source</th>
- <td>
- <a href="<?php echo $emote["source"] ?>"
- target="_blank"><?php echo $emote["source"] ?></a>
- </td>
- </tr>
- <?php endif; ?>
- </table>
- </section>
- <!-- Emote actions -->
- <form action="/system/emotes/verdict.php" method="post">
- <input type="text" name="id" value="<?php echo $emote["id"] ?>" style="display: none;">
- <input type="text" name="action" value="none" id="form-action" style="display: none;">
- <div class="column small-gap">
- <noscript>JavaScript is required!!!</noscript>
- <div class="box row small-gap">
- <button type="submit" class="grow green big" onclick="set_verdict('approve')">Make it
- public</button>
- <button type="submit" class="grow red big" onclick="set_verdict('reject')">Make it
- unlisted</button>
- </div>
- <div class="box">
- <div class="box navtab">Comment</div>
- <div class="box content">
- <textarea name="comment" id="form-comment"></textarea>
- </div>
- </div>
- </div>
- </form>
- </section>
- <?php endif; ?>
- </section>
- </div>
- </div>
-</body>
-
-<script>
- function set_verdict(verdict) {
- document.getElementById("form-action").setAttribute("value", verdict);
- }
-</script>
-
-</html> \ No newline at end of file
diff --git a/public/system/emotes/verdict.php b/public/system/emotes/verdict.php
deleted file mode 100644
index df2f5ba..0000000
--- a/public/system/emotes/verdict.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?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 = str_safe($_POST["id"], 32);
-$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"] ?? "", null, 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"] . '"'
- };
-
- if ($comment != null) {
- $contents .= " Mod's comment: $comment";
- }
-
- $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 ? 'unlisted' : 'set to 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
deleted file mode 100644
index 95b17a5..0000000
--- a/public/system/index.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?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 - <?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</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 (REPORTS_ENABLE && $_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/public/users.php b/public/users.php
deleted file mode 100644
index 6a6273e..0000000
--- a/public/users.php
+++ /dev/null
@@ -1,587 +0,0 @@
-<?php
-include_once "../src/config.php";
-include_once "../src/user.php";
-include_once "../src/partials.php";
-include_once "../src/utils.php";
-include_once "../src/accounts.php";
-include_once "../src/alert.php";
-include_once "../src/emote.php";
-
-authorize_user();
-
-$is_json = isset($_SERVER["HTTP_ACCEPT"]) && $_SERVER["HTTP_ACCEPT"] == "application/json";
-
-$id = $_GET["id"] ?? "";
-$alias_id = $_GET["alias_id"] ?? "";
-
-$db = new PDO(DB_URL, DB_USER, DB_PASS);
-
-if ($id == "" && $alias_id == "") {
- if (!ACCOUNT_PUBLIC_LIST) {
- generate_alert("/404.php", "The public list of accounts is disabled", 403);
- exit;
- }
-
- $page = max(1, intval($_GET["p"] ?? "1"));
- $limit = 25;
- $offset = ($page - 1) * $limit;
- $search = "%" . ($_GET["q"] ?? "") . "%";
- $stmt = $db->prepare("SELECT id, username, joined_at, last_active_at
- FROM users
- WHERE username LIKE ?
- ORDER BY last_active_at DESC LIMIT ? OFFSET ?");
- $stmt->bindParam(1, $search, PDO::PARAM_STR);
- $stmt->bindParam(2, $limit, PDO::PARAM_INT);
- $stmt->bindParam(3, $offset, PDO::PARAM_INT);
- $stmt->execute();
-
- $count_stmt = $db->prepare("SELECT COUNT(*) FROM users WHERE username LIKE ?");
- $count_stmt->execute([$search]);
-
- $total_users = $count_stmt->fetch()[0];
- $total_pages = ceil($total_users / $limit);
-
- if ($is_json) {
- header("Content-Type: application/json");
- echo json_encode([
- "status_code" => 200,
- "message" => null,
- "data" => [
- "all_user_count" => intval($all_user_count),
- "users" => $stmt->fetchAll(PDO::FETCH_ASSOC)
- ]
- ]);
- exit;
- }
-
- echo '' ?>
- <html>
-
- <head>
- <title>User list - <?php echo INSTANCE_NAME ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
- </head>
-
- <body>
- <div class="container">
- <div class="wrapper">
- <?php html_navigation_bar() ?>
- <section class="content row">
- <section class="sidebar">
- <?php html_navigation_search(); ?>
- </section>
- <section class="content">
- <section class="box">
- <div class="box navtab">
- <p><?php echo $total_users ?> Users - <?php echo "Page $page/$total_pages" ?></p>
- </div>
- <div class="box content">
- <?php
- if ($total_users != 0) {
- echo '<table>';
- echo '<tr>';
- echo '<th></th><th style="width:80%;">Username</th><th>Last active</th>';
- echo '<tr>';
- while ($row = $stmt->fetch()) {
- $diff = time() - strtotime($row["last_active_at"]);
-
- $last_active = "moments";
-
- if ($diff > 5) {
- $last_active = format_timestamp($diff);
- }
-
- echo '<tr><td>';
- echo '<img src="/static/';
- if (is_dir("static/userdata/avatars/" . $row["id"])) {
- echo 'userdata/avatars/' . $row["id"] . '/1x.webp';
- } else {
- echo 'img/defaults/profile_picture.png';
- }
- echo '" width="24" height="24">';
- echo '</td><td><a href="/users.php?id=' . $row["id"] . '">' . $row["username"] . '</a></td>';
- echo "<td>$last_active ago</td>";
- echo '</tr>';
- }
- echo '</table>';
- } else {
- echo '<p>Nothing found...</p>';
- }
- ?>
- </div>
- </section>
- <?php if ($total_pages > 1) {
- echo '' ?>
-
- <section class="box center row">
- <?php
- html_pagination($total_pages, $page, "/users.php?q=" . substr($search, 1, strlen($search) - 2));
- ?>
- </section>
- <?php
- }
- ?>
- </section>
- </div>
- </div>
- </body>
-
- </html>
- <?php ;
- exit;
-}
-
-// --- fetching user
-$user = null;
-
-// fetching user by connection
-if (isset($_GET["alias_id"])) {
- $alias_id = $_GET["alias_id"];
- $platform = $_GET["platform"] ?? "twitch";
-
- $stmt = $db->prepare("SELECT u.id FROM users u
- INNER JOIN connections co ON co.alias_id = ? AND co.platform = ?
- WHERE co.user_id = u.id
- ");
- $stmt->execute([$alias_id, $platform]);
-
- if ($row = $stmt->fetch()) {
- $user = User::get_user_by_id($db, $row["id"]);
- }
-}
-// fetching user by internal id
-else if (isset($_GET["id"])) {
- $user = User::get_user_by_id($db, $_GET["id"]);
-}
-
-if (!$user) {
- generate_alert("/404.php", "The user you requested cannot be found", 404);
- exit;
-}
-
-// User preferences
-$stmt = $db->prepare("SELECT * FROM user_preferences WHERE id = ?");
-$stmt->execute([$user->id]);
-
-$user_preferences = $stmt->fetch(PDO::FETCH_ASSOC);
-
-$public_profile = !$user_preferences["private_profile"] || $user->id == ($_SESSION["user_id"] ?? "");
-
-// fetching emote sets
-$emote_sets = Emoteset::get_all_user_emotesets($db, $user->id);
-$active_emote_set = null;
-foreach ($emote_sets as $es) {
- if ($es->is_default) {
- $active_emote_set = $es;
- break;
- }
-}
-
-// gathering uploaded emotes
-$uploaded_emotes = [];
-
-if ($public_profile) {
- $stmt = $db->prepare("SELECT e.id, e.code, e.uploaded_by, e.source, e.visibility
- FROM emotes e
- WHERE e.uploaded_by = ?
- ORDER BY e.created_at ASC
- ");
- $stmt->execute([$user->id]);
-
- $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
-
- foreach ($rows as $row) {
- array_push($uploaded_emotes, Emote::from_array_with_user($row, $db));
- }
-}
-
-// gathering actions
-$actions = [];
-
-if ($public_profile) {
- $stmt = $db->prepare("SELECT a.* FROM actions a WHERE a.user_id = ? ORDER BY a.created_at DESC LIMIT 15");
- $stmt->execute([$user->id]);
- $actions = $stmt->fetchAll(PDO::FETCH_ASSOC);
-}
-
-// TODO: add functionality
-
-// calculating contributions
-$stmt = $db->prepare("SELECT COUNT(*) FROM emotes WHERE uploaded_by = ?");
-$stmt->execute([$user->id]);
-$contributions = intval($stmt->fetch()[0]);
-
-$stmt = $db->prepare("SELECT COUNT(*) FROM ratings WHERE user_id = ?");
-$stmt->execute([$user->id]);
-
-$contributions += intval($stmt->fetch()[0]);
-
-// getting status
-$stmt = $db->prepare("SELECT * FROM roles r INNER JOIN role_assigns ra ON ra.user_id = ? WHERE ra.role_id = r.id");
-$stmt->execute([$user->id]);
-
-$role = $stmt->fetch(PDO::FETCH_ASSOC) ?? null;
-
-// getting reactions
-$stmt = $db->prepare("SELECT rate, COUNT(*) AS c FROM ratings WHERE user_id = ? GROUP BY rate ORDER BY c DESC");
-$stmt->execute([$user->id]);
-
-$fav_reactions = $stmt->fetchAll(PDO::FETCH_ASSOC);
-
-// getting favorite emote
-$fav_emote = 1;
-
-// getting custom badge
-$stmt = $db->prepare("SELECT b.* FROM badges b
- INNER JOIN user_badges ub ON ub.user_id = ?
- WHERE b.id = ub.badge_id
-");
-$stmt->execute([$user->id]);
-
-$custom_badge = null;
-if ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
- $custom_badge = $row;
-}
-
-if ($is_json) {
- $user_data = (array) $user;
-
- unset($user_data["private_profile"]);
-
- $user_data["stats"] = [
- "contributions" => $contributions,
- "favorite_reaction_id" => $fav_reactions,
- "favorite_emote_id" => $fav_emote
- ];
-
- $user_data["active_emote_set_id"] = $active_emote_set->id;
- $user_data["emote_sets"] = $emote_sets;
- $user_data["uploaded_emotes"] = $uploaded_emotes;
- $user_data["actions"] = $actions;
-
- json_response([
- "status_code" => 200,
- "message" => null,
- "data" => $user_data
- ]);
- exit;
-}
-?>
-
-<html>
-
-<head>
- <title><?php echo sprintf("%s - %s", $user->username, INSTANCE_NAME) ?></title>
- <link rel="stylesheet" href="/static/style.css">
- <link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon">
-</head>
-
-<body>
- <div class="background" style="background-image: url('/static/userdata/banners/<?php echo $user->id ?>/3x.webp');">
- <div class="background-layer"></div>
- </div>
-
- <div class="container">
- <div class="wrapper">
- <?php echo html_navigation_bar() ?>
- <section class="content row">
- <section class="sidebar flex column small-gap">
- <!-- User -->
- <section class="box">
- <div class="box navtab flex items-center small-gap">
- <?php
- echo $user->username;
-
- if ($custom_badge) {
- echo ' <img src="/static/userdata/badges/' . $custom_badge["id"] . '/1x.webp" alt="" title="Personal badge" />';
- }
- ?>
- </div>
- <div class="box content justify-center items-center">
- <?php
- echo '<img src="/static/';
- if (is_dir("static/userdata/avatars/" . $user->id)) {
- echo 'userdata/avatars/' . $user->id . '/3x.webp';
- } else {
- echo 'img/defaults/profile_picture.png';
- }
- echo '" width="192" height="192">';
- ?>
- </div>
- </section>
- <!-- Role -->
- <?php
- if ($role) {
- $bg_color_split = explode(":", $role["background_color"]);
- $bg_color = match ($bg_color_split[0]) {
- "solid" => sprintf("background: rgba(%s);", $bg_color_split[1]),
- "gradient" => sprintf("background: linear-gradient(0deg, rgba(%s), rgba(%s));", $bg_color_split[1], $bg_color_split[2]),
- "img" => sprintf("background-image: url('%s')", $bg_color_split[1]),
- default => ""
- };
-
- if ($role["badge_id"]): ?>
- <div class="box row small-gap items-center" style="<?php echo $bg_color; ?>">
- <div>
- <img src="/static/userdata/badges/<?php echo $role["badge_id"] ?>/3x.webp"
- alt="<?php echo $role["name"] ?>" width="54" height="54">
- </div>
- <div class="column">
- <p><?php echo $role["name"] ?></p>
- <i style="color: gray">Role</i>
- </div>
- </div>
- <?php endif;
- } ?>
- <!-- Stats -->
- <section class="box">
- <table class="vertical left">
- <tr>
- <th><img src="/static/img/icons/door_in.png"> Joined</th>
- <?php
- echo '<td title="';
- echo date("M d, Y H:i:s", $user->joined_at);
- echo ' UTC">about ' . format_timestamp(time() - $user->joined_at) . " ago</td>";
- ?>
- </tr>
- <tr>
- <th><img src="/static/img/icons/clock.png"> Last activity</th>
- <?php
- $diff = time() - $user->last_active_at;
- if ($diff > 60) {
- echo '<td title="';
- echo date("M d, Y H:i:s", $user->last_active_at);
- echo ' UTC">about ' . format_timestamp($diff) . " ago</td>";
- } else {
- echo '<td>Online</td>';
- }
- ?>
- </tr>
- <tr>
- <th><img src="/static/img/icons/star.png"> Contributions</th>
- <td><?php echo $contributions ?></td>
- </tr>
- <?php
- if ($fav_reactions != null) { ?>
- <tr>
- <th><img src="/static/img/icons/emoticon_happy.png"> Reactions</th>
- <td>
- <?php
- foreach ($fav_reactions as $reaction) {
- echo $reaction["c"] . ' <img src="/static/img/icons/ratings/' . $reaction["rate"] . '.png" alt="' . RATING_NAMES[$reaction["rate"]] . '" title="' . RATING_NAMES[$reaction["rate"]] . '">';
- }
- ?>
- </td>
- </tr><?php
- }
- ?>
- <?php
- $stmt = $db->prepare("SELECT code FROM emotes WHERE id = ?");
- $stmt->execute([$fav_emote]);
-
- if ($row = $stmt->fetch()) {
- echo '<tr>';
- echo '<th><img src="/static/img/icons/heart.png"> Favorite emote</th>';
- echo '<td>';
- echo "<a href=\"/emotes?id=$fav_emote\">";
- echo $row["code"] . ' <img src="/static/userdata/emotes/' . $fav_emote . '/1x.webp" width="16" height="16">';
- echo '</a></td></tr>';
- }
- ?>
- </table>
- </section>
- <!-- Buttons -->
- <section class="box flex column small-gap" style="display: inline-block;">
- <button onclick="open_tab('user-emotes')" id="user-emotes-button"><img
- src="/static/img/icons/emotes/emote.png" alt=""> Emotes</button>
- <button onclick="open_tab('user-emotesets')" id="user-emotesets-button"><img
- src="/static/img/icons/emotes/emote_folder.png" alt=""> Emote
- sets</button>
- <?php if ($public_profile): ?>
- <button onclick="open_tab('user-actions')" id="user-actions-button"><img
- src="/static/img/icons/tag_blue.png" alt=""> Actions</button>
- <button onclick="open_tab('user-uploadedemotes')" id="user-uploadedemotes-button"><img
- src="/static/img/icons/emotes/emote_go.png" alt=""> Uploaded
- emotes</button>
- <?php endif; ?>
- </section>
- </section>
- <section class="content" style="display: inline-block;">
- <!-- Current emoteset -->
- <section class="box grow user-tab" id="user-emotes">
- <div class="box navtab row">
- <div class="grow">
- <?php echo !empty($active_emote_set) ? $active_emote_set->name : "Emotes" ?>
- </div>
- <?php html_emotelist_mode() ?>
- </div>
- <div class="box content items flex">
- <?php if (!empty($active_emote_set)) {
- if (!empty($active_emote_set->emotes)) {
- html_display_emotes($active_emote_set->emotes);
- } else {
- echo '<p>No emotes found... ' . ((($_SESSION["user_id"] ?? "") == $id) ? 'Start adding emotes and they will appear here! :)</p>' : '</p>');
- }
- } else {
- echo "<p>This user doesn't have active emote set.</p>";
- }
- ?>
- </div>
- </section>
- <!-- Emote sets -->
- <section class="box grow user-tab" id="user-emotesets">
- <div class="box navtab">
- Emote sets
- </div>
- <div class="box content items">
- <?php
- if (!empty($emote_sets)) {
- html_display_emoteset($emote_sets);
- } else {
- echo '<p>No emote sets found... ' . ((($_SESSION["user_id"] ?? "") == $id) ? 'Start adding emotes and you will have one! :)</p>' : '</p>');
- }
- ?>
- </div>
- </section>
- <?php if ($public_profile): ?>
- <!-- Actions -->
- <section class="box grow user-tab" id="user-actions">
- <div class="box navtab">
- Actions
- <?php echo $user_preferences["private_profile"] ? " <img src='/static/img/icons/eye.png' alt='(Private)' title='You are the only one who sees this' />" : "" ?>
- </div>
- <div class="box content">
- <?php
- if (empty($actions)) {
- echo "<p>This user has done nothing bad or good...</p>";
- }
-
- foreach ($actions as $action) {
- echo '<div class="row">';
-
- list($action_name, $preposition, $icon_name) = match ($action["action_type"]) {
- "EMOTESET_ADD" => ["added", "to", "yes.png"],
- "EMOTESET_REMOVE" => ["removed", "from", "no.png"],
- "EMOTESET_ALIAS" => ["renamed", "in", "pencil.png"],
- "EMOTE_CREATE" => ["created", null, "new_emote.png"],
- "EMOTE_DELETE" => ["deleted", null, "deleted_emote.png"],
- "EMOTE_RENAME" => ["renamed", null, "renamed_emote.png"]
- };
-
- echo "<div><img src='/static/img/icons/$icon_name' width='16' /></div>";
-
- echo '<div class="column">';
- echo '<p>';
- echo '<i>' . $user->username . '</i> ';
-
- $payload = json_decode($action["action_payload"], true);
-
- list($action_root, $action_sub) = explode("_", $action["action_type"]);
-
- switch ($action_root) {
- case "EMOTESET": {
- $e_stmt = $db->prepare("SELECT COUNT(*) FROM emotes WHERE id = ?");
- $e_stmt->execute([$payload["emote"]["id"]]);
-
- echo "$action_name emote <a href=\"";
-
- if ($e_stmt->rowCount() == 1) {
- echo '/emotes?id=' . $payload["emote"]["id"] . '">';
- echo '<img src="/static/userdata/emotes/' . $payload["emote"]["id"] . '/1x.webp" height="16" /> ';
- } else {
- echo '">';
- }
-
- if (isset($payload["emote"]["original_code"])) {
- echo $payload["emote"]["original_code"] . '</a> to ';
- echo "<a href=\"";
-
- if ($e_stmt->rowCount() == 1) {
- echo '/emotes?id=' . $payload["emote"]["id"] . '">';
- echo '<img src="/static/userdata/emotes/' . $payload["emote"]["id"] . '/1x.webp" height="16" /> ';
- } else {
- echo '">';
- }
-
- echo $payload["emote"]["code"] . '</a>';
- } else {
- echo $payload["emote"]["code"] . '</a>';
- }
-
- $es_stmt = $db->prepare("SELECT COUNT(*) FROM emote_sets WHERE id = ?");
- $es_stmt->execute([$payload["emoteset"]["id"]]);
-
- echo " $preposition <a href=\"";
- if ($es_stmt->rowCount() == 1) {
- echo '/emotesets.php?id=' . $payload["emoteset"]["id"];
- }
-
- echo '">' . $payload["emoteset"]["name"] . '</a>';
- break;
- }
- case "EMOTE": {
- $e_stmt = $db->prepare("SELECT COUNT(*) FROM emotes WHERE id = ?");
- $e_stmt->execute([$payload["emote"]["id"]]);
-
- echo "$action_name emote <a href=\"";
-
- if ($e_stmt->rowCount() == 1) {
- echo '/emotes?id=' . $payload["emote"]["id"] . '">';
- echo '<img src="/static/userdata/emotes/' . $payload["emote"]["id"] . '/1x.webp" height="16" /> ';
- } else {
- echo '">';
- }
-
- echo $payload["emote"]["code"] . '</a>';
- break;
- }
- default: {
- echo "something that we don't know";
- break;
- }
- }
-
- echo '</p>';
- echo '<span class="font-small" style="color: gray;">[' . format_timestamp(time() - strtotime($action["created_at"])) . ' ago]</span> ';
- echo '</div></div>';
- }
- ?>
- </div>
- </section>
-
- <!-- Uploaded emotes -->
- <section class="box grow user-tab" id="user-uploadedemotes">
- <div class="box navtab row">
- <div class="grow">
- Uploaded emotes
- <?php echo $user_preferences["private_profile"] ? " <img src='/static/img/icons/eye.png' alt='(Private)' title='You are the only one who sees this' />" : "" ?>
- </div>
- </div>
- <div class="box content items">
- <?php html_display_emotes($uploaded_emotes); ?>
- </div>
- </section>
- <?php endif; ?>
- </section>
- </section>
- </div>
- </div>
-</body>
-
-<script>
- function open_tab(name) {
- const body = document.getElementById(name);
- const tabs = document.querySelectorAll(".user-tab");
-
- for (let tab of tabs) {
- tab.style.display = (tab.getAttribute("id") == name) ? "flex" : "none";
- }
- }
-
- open_tab("user-emotes");
-
- document.getElementById("sidebar").style.display = "block";
-</script>
-
-</html> \ No newline at end of file