polygon-website-foss/api/private/classes/pizzaboxer/ProjectPolygon/Users.php

277 lines
8.2 KiB
PHP

<?php
namespace pizzaboxer\ProjectPolygon;
use pizzaboxer\ProjectPolygon\Database;
use pizzaboxer\ProjectPolygon\Polygon;
use pizzaboxer\ProjectPolygon\PageBuilder;
class Users
{
const STAFF = 0; // this is not a normal user - just means every admin
const STAFF_CATALOG = 3; // catalog manager
const STAFF_MODERATOR = 1; // moderator
const STAFF_ADMINISTRATOR = 2; // administrator
static function GetIDFromName($username)
{
return Database::singleton()->run("SELECT id FROM users WHERE username = :username", [":username" => $username])->fetchColumn();
}
static function GetNameFromID($userId)
{
return Database::singleton()->run("SELECT username FROM users WHERE id = :uid", [":uid" => $userId])->fetchColumn();
}
static function GetInfoFromName($username)
{
return Database::singleton()->run("SELECT * FROM users WHERE username = :username", [":username" => $username])->fetch(\PDO::FETCH_OBJ);
}
static function GetInfoFromID($userId)
{
return Database::singleton()->run("SELECT * FROM users WHERE id = :uid", [":uid" => $userId])->fetch(\PDO::FETCH_OBJ);
}
static function GetInfoFromJobTicket()
{
if (!isset($_COOKIE['GameJobTicket'])) return false;
return Database::singleton()->run(
"SELECT users.* FROM GameJobSessions
INNER JOIN users ON users.id = GameJobSessions.UserID
WHERE Ticket = :Ticket AND Verified AND TimeCreated + 86400 > UNIX_TIMESTAMP()",
[":Ticket" => $_COOKIE['GameJobTicket']]
)->fetch(\PDO::FETCH_OBJ);
}
static function CheckIfFriends($userId1, $userId2, $status = false)
{
if ($status === false)
{
return Database::singleton()->run(
"SELECT * FROM friends WHERE :uid1 IN (requesterId, receiverId) AND :uid2 IN (requesterId, receiverId) AND NOT status = 2",
[":uid1" => $userId1, ":uid2" => $userId2]
)->fetch(\PDO::FETCH_OBJ);
}
else
{
return Database::singleton()->run(
"SELECT * FROM friends WHERE :uid1 IN (requesterId, receiverId) AND :uid2 IN (requesterId, receiverId) AND status = :status",
[":uid1" => $userId1, ":uid2" => $userId2, ":status" => $status]
)->fetch(\PDO::FETCH_OBJ);
}
}
static function GetFriendCount($userId)
{
return Database::singleton()->run("SELECT COUNT(*) FROM friends WHERE :uid IN (requesterId, receiverId) AND status = 1", [":uid" => $userId])->fetchColumn();
}
static function GetFriendRequestCount($userId)
{
return Database::singleton()->run("SELECT COUNT(*) FROM friends WHERE receiverId = :uid AND status = 0", [":uid" => $userId])->fetchColumn();
}
static function UpdatePing()
{
// i have never managed to make this work properly
// TODO - make this work properly for once
if(!SESSION) return false;
// update currency stipend
if(SESSION["user"]["nextCurrencyStipend"] <= time())
{
$days = floor((time() - SESSION["user"]["nextCurrencyStipend"]) / 86400);
if(!$days) $days = 1;
$stipend = $days * 10;
$nextstipend = SESSION["user"]["nextCurrencyStipend"] + (($days + 1) * 86400);
Database::singleton()->run(
"UPDATE users SET currency = currency + :stipend, nextCurrencyStipend = :nextstipend WHERE id = :uid",
[":stipend" => $stipend, ":nextstipend" => $nextstipend, ":uid" => SESSION["user"]["id"]]
);
}
// update presence
Database::singleton()->run(
"UPDATE users SET lastonline = UNIX_TIMESTAMP() WHERE id = :id; UPDATE sessions SET lastonline = UNIX_TIMESTAMP() WHERE sessionKey = :key",
[":id" => SESSION["user"]["id"], ":key" => SESSION["sessionKey"]]
);
}
static function GetOnlineStatus($UserID, $IsProfile)
{
// this is also a mess
$Status = (object)
[
"Online" => false,
"Text" => false,
"Attributes" => false
];
$Presence = Database::singleton()->run(
"SELECT lastonline, name AS PlaceName, assets.id AS PlaceID, ClientPresenceType FROM users
LEFT JOIN assets ON assets.id = ClientPresenceLocation AND ClientPresencePing + 65 > UNIX_TIMESTAMP()
WHERE users.id = :UserID",
[":UserID" => $UserID]
)->fetch();
if (SESSION && $Presence["PlaceID"] != null)
{
$Status->Online = true;
$Status->Text = sprintf(
($Presence["ClientPresenceType"] == "Visit" ? "Playing" : "Editing") . " <a href=\"/%s-place?id=%d\">%s</a>",
encode_asset_name($Presence["PlaceName"]),
$Presence["PlaceID"],
Polygon::FilterText($Presence["PlaceName"])
);
$Status->Attributes = " class=\"text-" . ($Presence["ClientPresenceType"] == "Visit" ? "success" : "danger") . " mb-0\"";
}
else if ($Presence["lastonline"] + 65 > time())
{
$Status->Online = true;
$Status->Text = "Website";
$Status->Attributes = " class=\"text-primary mb-0\"";
}
else
{
if ($IsProfile)
{
$Status->Text = "Offline";
}
else
{
$Status->Text = timeSince($Presence["lastonline"]);
}
$Status->Attributes = " class=\"text-muted mb-0\" data-toggle=\"tooltip\" data-placement=\"right\" title=\"".date('j/n/Y g:i A', $Presence["lastonline"])."\"";
}
if ($Status->Online && $IsProfile)
{
$Status->Text = "Online: {$Status->Text}";
}
return $Status;
}
static function GetUsersOnline()
{
return Database::singleton()->run("SELECT COUNT(*) FROM users WHERE lastonline+35 > UNIX_TIMESTAMP()")->fetchColumn();
}
static function RequireLogin($studio = false)
{
if(!SESSION) die(header("Location: /login?ReturnUrl=".urlencode($_SERVER['REQUEST_URI']).($studio?"&embedded=true":"")));
}
static function RequireLoggedOut()
{
if(SESSION) die(header("Location: /home"));
}
static function IsAdmin($level = self::STAFF)
{
if(!SESSION || SESSION["user"]["adminlevel"] == 0) return false;
if($level === self::STAFF) return true;
if(gettype($level) == "array")
{
if(in_array(SESSION["user"]["adminlevel"], $level)) return true;
}
else
{
if(SESSION["user"]["adminlevel"] == $level) return true;
}
return false;
}
static function RequireAdmin($level = self::STAFF)
{
if(!self::IsAdmin($level))
PageBuilder::instance()->errorCode(404);
if(!SESSION["user"]["twofa"])
PageBuilder::instance()->errorCode(403, [
"title" => "2FA is not enabled",
"text" => "Your account must have two-factor authentication enabled before you can do any administrative actions"
]);
}
static function GetUserModeration($userId)
{
return Database::singleton()->run(
"SELECT * FROM bans WHERE userId = :id AND NOT isDismissed ORDER BY id DESC LIMIT 1",
[":id" => $userId]
)->fetch(\PDO::FETCH_OBJ);
}
static function UndoUserModeration($userId, $admin = false)
{
$banInfo = self::GetUserModeration($userId);
if (!$banInfo) return false;
if (!$admin && ($banInfo->banType == 3 || ($banInfo->banType != 1 && $banInfo->timeEnds < time()))) return false;
Database::singleton()->run(
"UPDATE bans SET isDismissed = 1 WHERE userId = :id AND NOT isDismissed;
UPDATE users SET Banned = 0 WHERE id = :id",
[":id" => $userId]
);
return true;
}
static function LogStaffAction($action)
{
if(!SESSION || !SESSION["user"]["adminlevel"]) return false;
Database::singleton()->run("INSERT INTO stafflogs (time, adminId, action) VALUES (UNIX_TIMESTAMP(), :uid, :action)", [":uid" => SESSION["user"]["id"], ":action" => $action]);
}
static function GetAlternateAccounts($data)
{
$alts = [];
$usedIPs = [];
$usedIDs = [];
if(is_numeric($data)) // user id
{
$ips = Database::singleton()->run("SELECT loginIp FROM sessions WHERE userId = :uid GROUP BY loginIp", [":uid" => $data]);
}
else // ip address
{
$ips = Database::singleton()->run(
"SELECT loginIp FROM sessions
WHERE userId IN (SELECT userId FROM sessions WHERE loginIp = :ip GROUP BY userId) GROUP BY loginIp",
[":ip" => $data]
);
}
while($ip = $ips->fetch(\PDO::FETCH_OBJ))
{
if(in_array($ip->loginIp, $usedIPs)) continue;
$usedIPs[] = $ip->loginIp;
$altsquery = Database::singleton()->run(
"SELECT users.username, userId, users.jointime, loginIp FROM sessions
INNER JOIN users ON users.id = userId WHERE loginIp = :ip GROUP BY userId",
[":ip" => $ip->loginIp]
);
while($row = $altsquery->fetch(\PDO::FETCH_OBJ))
{
if(in_array($row->userId, $usedIDs)) continue;
$usedIDs[] = $row->userId;
$alts[] = ["username" => $row->username, "userid" => $row->userId, "created" => $row->jointime, "ip" => $row->loginIp];
}
}
return $alts;
}
}