diff options
| author | ilotterytea <iltsu@alright.party> | 2025-12-08 21:53:36 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-12-08 21:53:36 +0500 |
| commit | 57472eab3c7b035392c6a5aa240593ecaa7d1ccf (patch) | |
| tree | 9da30829290f225be2dab3d383549cbfda82ed19 /public | |
| parent | 6541d0f3888862ab049055fd418b700f73eed367 (diff) | |
upd: moved all /public/ files to the root folder
Diffstat (limited to 'public')
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 Binary files differdeleted file mode 100644 index ff8f9ad..0000000 --- a/public/static/favicon.ico +++ /dev/null diff --git a/public/static/img/404/1.webp b/public/static/img/404/1.webp Binary files differdeleted file mode 100644 index 7fc04a8..0000000 --- a/public/static/img/404/1.webp +++ /dev/null diff --git a/public/static/img/brand/big.webp b/public/static/img/brand/big.webp Binary files differdeleted file mode 100644 index c665251..0000000 --- a/public/static/img/brand/big.webp +++ /dev/null diff --git a/public/static/img/brand/mini.webp b/public/static/img/brand/mini.webp Binary files differdeleted file mode 100644 index ce0f91f..0000000 --- a/public/static/img/brand/mini.webp +++ /dev/null diff --git a/public/static/img/counter/0.png b/public/static/img/counter/0.png Binary files differdeleted file mode 100644 index 929946c..0000000 --- a/public/static/img/counter/0.png +++ /dev/null diff --git a/public/static/img/counter/1.png b/public/static/img/counter/1.png Binary files differdeleted file mode 100644 index f1c151d..0000000 --- a/public/static/img/counter/1.png +++ /dev/null diff --git a/public/static/img/counter/2.png b/public/static/img/counter/2.png Binary files differdeleted file mode 100644 index 7a5a2af..0000000 --- a/public/static/img/counter/2.png +++ /dev/null diff --git a/public/static/img/counter/3.png b/public/static/img/counter/3.png Binary files differdeleted file mode 100644 index c7c7598..0000000 --- a/public/static/img/counter/3.png +++ /dev/null diff --git a/public/static/img/counter/4.png b/public/static/img/counter/4.png Binary files differdeleted file mode 100644 index cd5b8b9..0000000 --- a/public/static/img/counter/4.png +++ /dev/null diff --git a/public/static/img/counter/5.png b/public/static/img/counter/5.png Binary files differdeleted file mode 100644 index 3455958..0000000 --- a/public/static/img/counter/5.png +++ /dev/null diff --git a/public/static/img/counter/6.png b/public/static/img/counter/6.png Binary files differdeleted file mode 100644 index c7f795d..0000000 --- a/public/static/img/counter/6.png +++ /dev/null diff --git a/public/static/img/counter/7.png b/public/static/img/counter/7.png Binary files differdeleted file mode 100644 index 925bb68..0000000 --- a/public/static/img/counter/7.png +++ /dev/null diff --git a/public/static/img/counter/8.png b/public/static/img/counter/8.png Binary files differdeleted file mode 100644 index 7cb611e..0000000 --- a/public/static/img/counter/8.png +++ /dev/null diff --git a/public/static/img/counter/9.png b/public/static/img/counter/9.png Binary files differdeleted file mode 100644 index f8ff704..0000000 --- a/public/static/img/counter/9.png +++ /dev/null diff --git a/public/static/img/defaults/profile_picture.png b/public/static/img/defaults/profile_picture.png Binary files differdeleted file mode 100644 index caaab1a..0000000 --- a/public/static/img/defaults/profile_picture.png +++ /dev/null diff --git a/public/static/img/icons/bin.png b/public/static/img/icons/bin.png Binary files differdeleted file mode 100644 index 375b8bf..0000000 --- a/public/static/img/icons/bin.png +++ /dev/null diff --git a/public/static/img/icons/clock.png b/public/static/img/icons/clock.png Binary files differdeleted file mode 100644 index e2672c2..0000000 --- a/public/static/img/icons/clock.png +++ /dev/null diff --git a/public/static/img/icons/connect.png b/public/static/img/icons/connect.png Binary files differdeleted file mode 100644 index 024138e..0000000 --- a/public/static/img/icons/connect.png +++ /dev/null diff --git a/public/static/img/icons/connections/twitch.webp b/public/static/img/icons/connections/twitch.webp Binary files differdeleted file mode 100644 index c2882b4..0000000 --- a/public/static/img/icons/connections/twitch.webp +++ /dev/null diff --git a/public/static/img/icons/disconnect.png b/public/static/img/icons/disconnect.png Binary files differdeleted file mode 100644 index b335cb1..0000000 --- a/public/static/img/icons/disconnect.png +++ /dev/null diff --git a/public/static/img/icons/door_in.png b/public/static/img/icons/door_in.png Binary files differdeleted file mode 100644 index 41676a0..0000000 --- a/public/static/img/icons/door_in.png +++ /dev/null diff --git a/public/static/img/icons/door_out.png b/public/static/img/icons/door_out.png Binary files differdeleted file mode 100644 index 2541d2b..0000000 --- a/public/static/img/icons/door_out.png +++ /dev/null diff --git a/public/static/img/icons/emotes/emote.png b/public/static/img/icons/emotes/emote.png Binary files differdeleted file mode 100644 index 3cf0a16..0000000 --- a/public/static/img/icons/emotes/emote.png +++ /dev/null diff --git a/public/static/img/icons/emotes/emote_folder.png b/public/static/img/icons/emotes/emote_folder.png Binary files differdeleted file mode 100644 index 2f8951f..0000000 --- a/public/static/img/icons/emotes/emote_folder.png +++ /dev/null diff --git a/public/static/img/icons/emotes/emote_go.png b/public/static/img/icons/emotes/emote_go.png Binary files differdeleted file mode 100644 index 36ae3f6..0000000 --- a/public/static/img/icons/emotes/emote_go.png +++ /dev/null diff --git a/public/static/img/icons/emoticon_happy.png b/public/static/img/icons/emoticon_happy.png Binary files differdeleted file mode 100644 index 6b7336e..0000000 --- a/public/static/img/icons/emoticon_happy.png +++ /dev/null diff --git a/public/static/img/icons/eye.png b/public/static/img/icons/eye.png Binary files differdeleted file mode 100644 index 564a1a9..0000000 --- a/public/static/img/icons/eye.png +++ /dev/null diff --git a/public/static/img/icons/heart.png b/public/static/img/icons/heart.png Binary files differdeleted file mode 100644 index d9ee53e..0000000 --- a/public/static/img/icons/heart.png +++ /dev/null diff --git a/public/static/img/icons/inbox/0.png b/public/static/img/icons/inbox/0.png Binary files differdeleted file mode 100644 index c149c2b..0000000 --- a/public/static/img/icons/inbox/0.png +++ /dev/null diff --git a/public/static/img/icons/inbox/1.png b/public/static/img/icons/inbox/1.png Binary files differdeleted file mode 100644 index 89c8129..0000000 --- a/public/static/img/icons/inbox/1.png +++ /dev/null diff --git a/public/static/img/icons/inbox/2.png b/public/static/img/icons/inbox/2.png Binary files differdeleted file mode 100644 index 7348aed..0000000 --- a/public/static/img/icons/inbox/2.png +++ /dev/null diff --git a/public/static/img/icons/link_break.png b/public/static/img/icons/link_break.png Binary files differdeleted file mode 100644 index 5235753..0000000 --- a/public/static/img/icons/link_break.png +++ /dev/null diff --git a/public/static/img/icons/new_emote.png b/public/static/img/icons/new_emote.png Binary files differdeleted file mode 100644 index 82d263e..0000000 --- a/public/static/img/icons/new_emote.png +++ /dev/null diff --git a/public/static/img/icons/no.png b/public/static/img/icons/no.png Binary files differdeleted file mode 100644 index c149c2b..0000000 --- a/public/static/img/icons/no.png +++ /dev/null diff --git a/public/static/img/icons/pencil.png b/public/static/img/icons/pencil.png Binary files differdeleted file mode 100644 index 0bfecd5..0000000 --- a/public/static/img/icons/pencil.png +++ /dev/null diff --git a/public/static/img/icons/ratings/-1.png b/public/static/img/icons/ratings/-1.png Binary files differdeleted file mode 100644 index 38f492a..0000000 --- a/public/static/img/icons/ratings/-1.png +++ /dev/null diff --git a/public/static/img/icons/ratings/1.png b/public/static/img/icons/ratings/1.png Binary files differdeleted file mode 100644 index 0b01c2b..0000000 --- a/public/static/img/icons/ratings/1.png +++ /dev/null diff --git a/public/static/img/icons/ratings/brimstone.webp b/public/static/img/icons/ratings/brimstone.webp Binary files differdeleted file mode 100644 index 98b0d62..0000000 --- a/public/static/img/icons/ratings/brimstone.webp +++ /dev/null diff --git a/public/static/img/icons/star.png b/public/static/img/icons/star.png Binary files differdeleted file mode 100644 index b88c857..0000000 --- a/public/static/img/icons/star.png +++ /dev/null diff --git a/public/static/img/icons/table.png b/public/static/img/icons/table.png Binary files differdeleted file mode 100644 index abcd936..0000000 --- a/public/static/img/icons/table.png +++ /dev/null diff --git a/public/static/img/icons/tag_blue.png b/public/static/img/icons/tag_blue.png Binary files differdeleted file mode 100644 index 9757fc6..0000000 --- a/public/static/img/icons/tag_blue.png +++ /dev/null diff --git a/public/static/img/icons/user.png b/public/static/img/icons/user.png Binary files differdeleted file mode 100644 index 79f35cc..0000000 --- a/public/static/img/icons/user.png +++ /dev/null diff --git a/public/static/img/icons/world.png b/public/static/img/icons/world.png Binary files differdeleted file mode 100644 index 68f21d3..0000000 --- a/public/static/img/icons/world.png +++ /dev/null diff --git a/public/static/img/icons/yes.png b/public/static/img/icons/yes.png Binary files differdeleted file mode 100644 index 89c8129..0000000 --- a/public/static/img/icons/yes.png +++ /dev/null diff --git a/public/static/img/software/tinyrino/icon.png b/public/static/img/software/tinyrino/icon.png Binary files differdeleted file mode 100644 index 8f5bce3..0000000 --- a/public/static/img/software/tinyrino/icon.png +++ /dev/null diff --git a/public/static/img/software/tinyrino/screenshots/1.png b/public/static/img/software/tinyrino/screenshots/1.png Binary files differdeleted file mode 100644 index 8e4d993..0000000 --- a/public/static/img/software/tinyrino/screenshots/1.png +++ /dev/null diff --git a/public/static/img/software/tinyrino/screenshots/2.png b/public/static/img/software/tinyrino/screenshots/2.png Binary files differdeleted file mode 100644 index ec21185..0000000 --- a/public/static/img/software/tinyrino/screenshots/2.png +++ /dev/null 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 |
