mirror of
https://github.com/OPSnet/Gazelle.git
synced 2026-01-16 18:04:34 -05:00
689 lines
26 KiB
PHP
689 lines
26 KiB
PHP
<?php
|
|
|
|
use Gazelle\Util\Mail;
|
|
|
|
authorize();
|
|
|
|
function translateUserStatus($status) {
|
|
switch ($status) {
|
|
case 0:
|
|
return 'Unconfirmed';
|
|
case 1:
|
|
return 'Enabled';
|
|
case 2:
|
|
return 'Disabled';
|
|
default:
|
|
return $status;
|
|
}
|
|
}
|
|
|
|
function enabledStatus($status) {
|
|
switch ($status) {
|
|
case 0:
|
|
return 'Disabled';
|
|
case 1:
|
|
return 'Enabled';
|
|
default:
|
|
return $status;
|
|
}
|
|
}
|
|
|
|
function revoked(bool $state) {
|
|
return $state ? 'revoked' : 'restored';
|
|
}
|
|
|
|
if (!check_perms('users_mod')) {
|
|
error(403);
|
|
}
|
|
|
|
$userMan = new Gazelle\Manager\User;
|
|
$user = $userMan->findById((int)$_POST['userid']);
|
|
if (is_null($user)) {
|
|
header("Location: log.php?search=User+$userId");
|
|
exit;
|
|
}
|
|
$userId = $user->id();
|
|
$ownProfile = $userId === $LoggedUser['ID'];
|
|
|
|
// Variables for database input
|
|
$class = (int)$_POST['Class'];
|
|
$username = trim($_POST['Username']);
|
|
$title = trim($_POST['Title']);
|
|
$adminComment = trim($_POST['AdminComment']);
|
|
$secondaryClasses = array_filter(
|
|
array_map(function ($id) { return (int)$id; }, $_POST['secondary_classes'] ?? [] ),
|
|
function ($id) { return $id > 0; }
|
|
);
|
|
sort($secondaryClasses);
|
|
$visible = isset($_POST['Visible']) ? '1' : '0';
|
|
$unlimitedDownload = isset($_POST['unlimitedDownload']) ? 1 : 0;
|
|
$invites = (int)$_POST['Invites'];
|
|
$supportFor = trim($_POST['SupportFor']);
|
|
$changePassword = !empty($_POST['ChangePassword']);
|
|
$warned = isset($_POST['Warned']) ? 1 : 0;
|
|
$uploaded = $downloaded = $bonusPoints = null;
|
|
if (isset($_POST['Uploaded']) && isset($_POST['Downloaded'])) {
|
|
$uploaded = ($_POST['Uploaded'] === '' ? 0 : $_POST['Uploaded']);
|
|
if ($arithmetic = strpbrk($uploaded, '+-')) {
|
|
$uploaded += max(-$uploaded, Format::get_bytes($arithmetic));
|
|
}
|
|
$downloaded = ($_POST['Downloaded'] === '' ? 0 : $_POST['Downloaded']);
|
|
if ($arithmetic = strpbrk($downloaded, '+-')) {
|
|
$downloaded += max(-$downloaded, Format::get_bytes($arithmetic));
|
|
}
|
|
if (!is_number($uploaded) || !is_number($downloaded)) {
|
|
error(0);
|
|
}
|
|
}
|
|
if (isset($_POST['BonusPoints'])) {
|
|
$bonusPoints = empty($_POST['BonusPoints']) ? 0.0 : (float)$_POST['BonusPoints'];
|
|
}
|
|
$Collages = (int)$_POST['Collages'] ?? 0;
|
|
$flTokens = isset($_POST['FLTokens']) ? trim($_POST['FLTokens']) : 0;
|
|
if (!is_number($flTokens)) {
|
|
error(0);
|
|
}
|
|
|
|
$warnLength = (int)$_POST['WarnLength'];
|
|
$extendWarning = $_POST['ExtendWarning'] ?? '---';
|
|
$reduceWarning = $_POST['ReduceWarning'] ?? '---';
|
|
$warnReason = trim($_POST['WarnReason']);
|
|
$userReason = trim($_POST['UserReason']);
|
|
$disableAvatar = isset($_POST['DisableAvatar']) ? 1 : 0;
|
|
$disableInvites = isset($_POST['DisableInvites']) ? 1 : 0;
|
|
$disablePosting = isset($_POST['DisablePosting']) ? 1 : 0;
|
|
$disablePoints = isset($_POST['DisablePoints']) ? 1 : 0;
|
|
$disableForums = isset($_POST['DisableForums']) ? 1 : 0;
|
|
$disableTagging = isset($_POST['DisableTagging']) ? 1 : 0;
|
|
$disableUpload = isset($_POST['DisableUpload']) ? 1 : 0;
|
|
$disableWiki = isset($_POST['DisableWiki']) ? 1 : 0;
|
|
$disablePM = isset($_POST['DisablePM']) ? 1 : 0;
|
|
$disableIRC = isset($_POST['DisableIRC']) ? 1 : 0;
|
|
$disableRequests = isset($_POST['DisableRequests']) ? 1 : 0;
|
|
$disableLeech = isset($_POST['DisableLeech']) ? 0 : 1;
|
|
$lockAccount = isset($_POST['LockAccount']) ? 1 : 0;
|
|
$lockType = (int)$_POST['LockType'];
|
|
|
|
$enableUser = (int)$_POST['UserStatus'];
|
|
$resetRatioWatch = $_POST['ResetRatioWatch'] ?? 0 ? 1 : 0;
|
|
$resetIPHistory = $_POST['ResetIPHistory'] ?? 0;
|
|
$resetPasskey = isset($_POST['ResetPasskey']) ? 1 : 0;
|
|
$resetAuthkey = isset($_POST['ResetAuthkey']) ? 1 : 0;
|
|
$logoutSession = isset($_POST['Logout']) ? 1 : 0;
|
|
$sendHackedMail = isset($_POST['SendHackedMail']) ? 1 : 0;
|
|
if ($sendHackedMail && !empty(trim($_POST['HackedEmail']))) {
|
|
$hackedEmail = trim($_POST['HackedEmail']);
|
|
} else {
|
|
$sendHackedMail = false;
|
|
}
|
|
$mergeStatsFrom = trim($_POST['MergeStatsFrom']);
|
|
$reason = trim($_POST['Reason']);
|
|
|
|
$cur = $user->info();
|
|
if ($_POST['comment_hash'] != $cur['CommentHash']) {
|
|
error("Somebody else has moderated this user since you loaded it. Please go back and refresh the page.");
|
|
}
|
|
|
|
// NOW that we know the class of the current user, we can see if one staff member is trying to hax0r us.
|
|
if (!check_perms('users_mod')) {
|
|
error(403);
|
|
}
|
|
|
|
if ($mergeStatsFrom && ($downloaded != $cur['Downloaded'] || $uploaded != $cur['Uploaded'])) {
|
|
// Too make make-work code to deal with this unlikely eventuality
|
|
error("Do not transfer buffer and edit upload/download in the same operation.");
|
|
}
|
|
|
|
$donorMan = new Gazelle\Manager\Donation;
|
|
$donorMan->twig($Twig);
|
|
if (!empty($_POST['donor_points_submit']) && !empty($_POST['donation_value']) && is_numeric($_POST['donation_value'])) {
|
|
$donorMan->moderatorDonate($user, $_POST['donation_value'], $_POST['donation_currency'], $_POST['donation_reason'], $LoggedUser['ID']);
|
|
} elseif (!empty($_POST['donor_values_submit'])) {
|
|
$donorMan->moderatorAdjust($user, $_POST['donor_rank_delta'], $_POST['total_donor_rank_delta'], $_POST['reason'], $LoggedUser['ID']);
|
|
}
|
|
|
|
$tracker = new Gazelle\Tracker;
|
|
|
|
// If we're deleting the user, we can ignore all the other crap
|
|
if ($_POST['UserStatus'] === 'delete' && check_perms('users_delete_users')) {
|
|
(new Gazelle\Log)->general("User account $userId (".$cur['Username'].") was deleted by ".$LoggedUser['Username']);
|
|
$user->remove();
|
|
$tracker->update_tracker('remove_user', ['passkey' => $cur['torrent_pass']]);
|
|
header("Location: log.php?search=User+$userId");
|
|
exit;
|
|
}
|
|
|
|
// User was not deleted. Perform other stuff.
|
|
|
|
$editSummary = [];
|
|
$trackerUserUpdates = ['passkey' => $cur['torrent_pass']];
|
|
|
|
if (!$lockType || $lockAccount == 0) {
|
|
if ($cur['locked_account']) {
|
|
$user->unlock();
|
|
$Cache->delete_value('user_' . $cur['torrent_pass']);
|
|
$editSummary[] = 'account unlocked';
|
|
}
|
|
} elseif ($lockType) {
|
|
if ($cur['locked_account'] !== $lockType) {
|
|
if ($user->lock($lockType)) {
|
|
$Cache->delete_value('user_' . $cur['torrent_pass']);
|
|
$editSummary[] = empty($cur['locked_account'])
|
|
? "Account locked (type $lockType)"
|
|
: "Account lock type changed to $lockType";
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($_POST['ResetRatioWatch'] ?? 0 && check_perms('users_edit_reset_keys')) {
|
|
$user->resetRatioWatch();
|
|
$editSummary[] = 'RatioWatch history reset';
|
|
}
|
|
|
|
if ($resetIPHistory && check_perms('users_edit_reset_keys')) {
|
|
$user->resetIpHistory();
|
|
$editSummary[] = 'IP history cleared';
|
|
}
|
|
|
|
if ($_POST['ResetEmailHistory'] ?? 0 && check_perms('users_edit_reset_keys')) {
|
|
$user->resetEmailHistory($username . '@' . SITE_HOST, $resetIPHistory ? '127.0.0.1' : $cur['IP']);
|
|
$editSummary[] = 'email history cleared';
|
|
}
|
|
|
|
if ($_POST['ResetSnatchList'] ?? 0 && check_perms('users_edit_reset_keys')) {
|
|
$user->resetSnatched();
|
|
$editSummary[] = 'snatch list cleared';
|
|
}
|
|
|
|
if ($_POST['ResetDownloadList'] ?? 0 && check_perms('users_edit_reset_keys')) {
|
|
$user->resetDownloadList();
|
|
$editSummary[] = 'download list cleared';
|
|
}
|
|
|
|
if ($logoutSession && check_perms('users_logout')) {
|
|
$editSummary[] = "logged out of all sessions (n=" . (new Gazelle\Session($userId))->dropAll() . ")";
|
|
}
|
|
|
|
if ($flTokens != $cur['FLTokens'] && ($editRatio || check_perms('admin_manage_user_fls'))) {
|
|
$editSummary[] = "freeleech tokens changed from {$cur['FLTokens']} to $flTokens";
|
|
}
|
|
|
|
$newBonusPoints = false;
|
|
if ($bonusPoints != floatval($cur['BonusPoints']) && $bonusPoints != floatval($_POST['OldBonusPoints'])
|
|
&& (check_perms('users_edit_ratio') || (check_perms('users_edit_own_ratio') && $ownProfile))) {
|
|
$newBonusPoints = $bonusPoints;
|
|
$editSummary[] = "bonus points changed from {$cur['BonusPoints']} to {$bonusPoints}";
|
|
}
|
|
|
|
if ($Collages != $Cur['Collages'] && $Collages != (int)$_POST['OldCollages']
|
|
&& (check_perms('users_edit_ratio') || (check_perms('users_edit_own_ratio') && $ownProfile))) {
|
|
$set[] = 'collages = ?';
|
|
$args[] = $Collages;
|
|
$EditSummary[] = "personal collages changed from {$Cur['Collages']} to {$Collages}";
|
|
}
|
|
|
|
if ($unlimitedDownload != $cur['unlimitedDownload'] && check_perms('admin_rate_limit_manage')) {
|
|
if ($user->toggleUnlimitedDownload($unlimitedDownload)) {
|
|
$editSummary[] = "unlimited download " . strtolower(enabledStatus($unlimitedDownload));
|
|
}
|
|
}
|
|
|
|
$leechSet = [];
|
|
$leechArgs = [];
|
|
$editRatio = check_perms('users_edit_ratio') || (check_perms('users_edit_own_ratio') && $ownProfile);
|
|
if ($editRatio) {
|
|
if ($uploaded != $cur['Uploaded'] && $uploaded != $_POST['OldUploaded']) {
|
|
$leechSet[] = 'Uploaded = ?';
|
|
$leechArgs[] = $uploaded;
|
|
$editSummary[] = "uploaded changed from " . Format::get_size($cur['Uploaded'])
|
|
. ' to ' . Format::get_size($uploaded)
|
|
. " (delta " . Format::get_size($uploaded - $cur['Uploaded']) . ")";
|
|
}
|
|
if ($downloaded != $cur['Downloaded'] && $downloaded != $_POST['OldDownloaded']) {
|
|
$leechSet[] = 'Downloaded = ?';
|
|
$leechArgs[] = $downloaded;
|
|
$editSummary[] = "downloaded changed from " . Format::get_size($cur['Downloaded'])
|
|
. ' to ' . Format::get_size($downloaded)
|
|
. " (delta " . Format::get_size($downloaded - $cur['Downloaded']) . ")";
|
|
}
|
|
}
|
|
|
|
// Begin building users_main/users_info update
|
|
$set = [];
|
|
$args = [];
|
|
|
|
$Classes = $userMan->classList();
|
|
if ($Classes[$class]['Level'] != $cur['Class']
|
|
&& (
|
|
($Classes[$class]['Level'] < $LoggedUser['Class'] && check_perms('users_promote_below'))
|
|
|| ($Classes[$class]['Level'] <= $LoggedUser['Class'] && check_perms('users_promote_to'))
|
|
)) {
|
|
$set[] = 'PermissionID = ?';
|
|
$args[] = $class;
|
|
$editSummary[] = 'class changed to ' . $userMan->userclassName($class);
|
|
|
|
if ($user->supportCount($class, $cur['PermissionID']) === 2) {
|
|
if ($Classes[$class]['Level'] < $cur['Class']) {
|
|
$supportFor = '';
|
|
}
|
|
$Cache->delete_value('staff_ids');
|
|
}
|
|
$Cache->delete_value("donor_info_$userId");
|
|
}
|
|
|
|
if ($username !== $cur['Username'] && check_perms('users_edit_usernames')) {
|
|
if (in_array($username, ['0', '1'])) {
|
|
error('You cannot set a username of "0" or "1".');
|
|
header("Location: user.php?id=$userId");
|
|
exit;
|
|
} elseif (strtolower($username) !== strtolower($cur['Username'])) {
|
|
$found = $userMan->findByUsername($username);
|
|
if ($found) {
|
|
$id = $found->id();
|
|
error("Username already in use by <a href=\"user.php?id=$id\">$username</a>");
|
|
header("Location: user.php?id=$id");
|
|
exit;
|
|
}
|
|
$set[] = 'Username = ?';
|
|
$args[] = $username;
|
|
$editSummary[] = "username changed from ".$cur['Username']." to $username";
|
|
}
|
|
}
|
|
|
|
if ($title != $cur['Title'] && check_perms('users_edit_titles')) {
|
|
// Using the unescaped value for the test to avoid confusion
|
|
if (mb_strlen($_POST['Title']) > 1024) {
|
|
error("Custom titles have a maximum length of 1,024 characters.");
|
|
header("Location: user.php?id=$userId");
|
|
exit;
|
|
} else {
|
|
$set[] = 'Title = ?';
|
|
$args[] = $title;
|
|
$editSummary[] = "title changed to [code]{$title}[/code]";
|
|
}
|
|
}
|
|
|
|
if (check_perms('users_warn')) {
|
|
if ($warned == 0) {
|
|
if (!is_null($cur['Warned'])) {
|
|
$set[] = "Warned = ?";
|
|
$args[] = null;
|
|
$editSummary[] = 'warning removed';
|
|
}
|
|
} elseif (
|
|
(is_null($cur['Warned']) && $warnLength != '---')
|
|
||
|
|
($cur['Warned'] && ($extendWarning != '---' || $reduceWarning != '---'))
|
|
) {
|
|
if (is_null($cur['Warned'])) {
|
|
$weeksChange = $warnLength;
|
|
$duration = 'week' . plural($warnLength);
|
|
$message = [
|
|
'summary' => "warned for $warnLength $duration",
|
|
'subject' => 'You have received a warning',
|
|
'body' => "You have been [url=wiki.php?action=article&name=warnings]warned[/url] for $warnLength $duration",
|
|
];
|
|
} else {
|
|
$weeksChange = ($extendWarning != '---') ? $extendWarning : -$reduceWarning;
|
|
$nrWeeks = abs($weeksChange);
|
|
$duration = 'week' . plural($nrWeeks);
|
|
$action = $weeksChange > 0 ? 'extended' : 'reduced';
|
|
$message = [
|
|
'summary' => "warning $action $nrWeeks $duration",
|
|
'subject' => "Your warning has been $action by $nrWeeks $duration",
|
|
'body' => "Your warning has been $action by $nrWeeks $duration",
|
|
];
|
|
}
|
|
$set[] = "Warned = now() + INTERVAL ? WEEK";
|
|
$args[] = $weeksChange;
|
|
$expiry = $user->endWarningDate($weeksChange);
|
|
$message['body'] .= ", by [user]" . $LoggedUser['Username'] . "[/user]."
|
|
. " The reason given was:\n[quote]{$warnReason}[/quote]. The warning will expire on $expiry."
|
|
. "\n\nThis is an automated message. You may reply for more information if necessary.";
|
|
$userMan->sendPM($userId, $LoggedUser['ID'], $message['subject'], $message['body']);
|
|
$editSummary[] = $message['summary'] . ", expiry: $expiry"
|
|
. ($warnReason ? ", reason: \"$warnReason\"" : '');
|
|
}
|
|
}
|
|
|
|
$removedClasses = [];
|
|
$addedClasses = [];
|
|
if (check_perms('users_promote_below') || check_perms('users_promote_to')) {
|
|
$currentClasses = array_keys($cur['secondary_class']);
|
|
sort($currentClasses);
|
|
if (implode(',', $currentClasses) != implode(',', $secondaryClasses)) {
|
|
$removedClasses = array_diff($currentClasses, $secondaryClasses);
|
|
$addedClasses = array_diff($secondaryClasses, $currentClasses);
|
|
if (!empty($removedClasses)) {
|
|
$names = array_map(function ($c) use ($userMan) { return $userMan->userclassName($c); }, $removedClasses);
|
|
$editSummary[] = 'secondary classes dropped: ' . implode(', ', $names);
|
|
}
|
|
if (!empty($addedClasses)) {
|
|
$names = array_map(function ($c) use ($userMan) { return $userMan->userclassName($c); }, $addedClasses);
|
|
$editSummary[] = "secondary classes added: " . implode(', ', $names);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (check_perms('users_mod')) {
|
|
$fMan = new Gazelle\Manager\Forum;
|
|
$restricted = array_map(function ($id) {return (int)$id;}, array_unique(explode(',', trim($_POST['RestrictedForums']))));
|
|
sort($restricted);
|
|
$restrictedIds = [];
|
|
$restrictedNames = [];
|
|
foreach ($restricted as $forumId) {
|
|
$forum = $fMan->findById($forumId);
|
|
if (!is_null($forum)) {
|
|
$restrictedIds[] = $forumId;
|
|
$restrictedNames[] = $forum->name() . "($forumId)";
|
|
}
|
|
}
|
|
$restrictedForums = implode(',', $restrictedIds);
|
|
if ($restrictedForums != $cur['RestrictedForums']) {
|
|
$set[] = "RestrictedForums = ?";
|
|
$args[] = $restrictedForums;
|
|
$editSummary[] = "prohibited forum(s): " . ($restrictedForums == '' ? 'none' : implode(', ', $restrictedNames));
|
|
}
|
|
|
|
$permitted = array_map(function ($id) {return (int)$id;}, array_unique(explode(',', trim($_POST['PermittedForums']))));
|
|
sort($permitted);
|
|
$permittedIds = [];
|
|
$permittedNames = [];
|
|
foreach ($permitted as $forumId) {
|
|
$forum = $fMan->findById($forumId);
|
|
if (!is_null($forum)) {
|
|
$permittedIds[] = $forumId;
|
|
$permittedNames[] = $forum->name() . "($forumId)";
|
|
}
|
|
}
|
|
$permittedForums = implode(',', $permittedIds);
|
|
if ($permittedForums != $cur['PermittedForums']) {
|
|
$set[] = "PermittedForums = ?";
|
|
$args[] = $permittedForums;
|
|
$editSummary[] = "permitted forum(s): " . ($permittedForums == '' ? 'none' : implode(', ', $permittedNames));
|
|
}
|
|
}
|
|
|
|
if ($visible != $cur['Visible'] && check_perms('users_make_invisible')) {
|
|
$set[] = 'Visible = ?';
|
|
$args[] = $visible ? '1' : '0';
|
|
$trackerUserUpdates['visible'] = $visible;
|
|
$editSummary[] = 'visibility ' . ($visible ? 'on' : 'off');
|
|
}
|
|
|
|
if ($invites != $cur['Invites'] && check_perms('users_edit_invites')) {
|
|
$set[] = 'Invites = ?';
|
|
$args[] = $invites;
|
|
$editSummary[] = "number of invites changed from {$cur['Invites']} to $invites";
|
|
}
|
|
|
|
if ($supportFor != $cur['SupportFor'] && (check_perms('admin_manage_fls') || (check_perms('users_mod') && $ownProfile))) {
|
|
$set[] = "SupportFor = ?";
|
|
$args[] = $supportFor;
|
|
$editSummary[] = "First-Line Support status changed to \"$supportFor\"";
|
|
}
|
|
|
|
$privChange = [];
|
|
|
|
if (check_perms('users_disable_any')) {
|
|
if ($disableLeech != $cur['can_leech']) {
|
|
$privChange[] = 'Your leeching privileges have been ' . revoked($disableLeech);
|
|
$set[] = "can_leech = ?";
|
|
$args[] = $disableLeech ? '1' : '0';
|
|
$trackerUserUpdates['can_leech'] = $disableLeech;
|
|
$editSummary[] = "leeching status changed ("
|
|
. enabledStatus($cur['can_leech'])." → ".enabledStatus($disableLeech).")";
|
|
}
|
|
if ($disableInvites != $cur['DisableInvites']) {
|
|
$set[] = "DisableInvites = ?";
|
|
$args[] = $disableInvites ? '1' : '0';
|
|
$privChange[] = 'Your invite privileges have been ' . revoked($disableInvites);
|
|
$editSummary[] = 'invites privileges ' . revoked($disableInvites);
|
|
}
|
|
if ($disableAvatar != $cur['DisableAvatar'] && check_perms('users_disable_any')) {
|
|
$set[] = "DisableAvatar = ?";
|
|
$args[] = $disableAvatar ? '1' : '0';
|
|
$privChange[] = 'Your avatar privileges have been ' . revoked($disableAvatar);
|
|
$editSummary[] = 'avatar privileges ' . revoked($disableAvatar);
|
|
}
|
|
if ($disablePoints != $cur['DisablePoints']) {
|
|
$set[] = "DisablePoints = ?";
|
|
$args[] = $disablePoints ? '1' : '0';
|
|
$privChange[] = 'Your bonus points acquisition has been ' . revoked($disablePoints);
|
|
$editSummary[] = 'points privileges ' . revoked($disablePoints);
|
|
}
|
|
if ($disableTagging != $cur['DisableTagging']) {
|
|
$set[] = "DisableTagging = ?";
|
|
$args[] = $disableTagging ? '1' : '0';
|
|
$privChange[] = 'Your tagging privileges have been ' . revoked($disableTagging);
|
|
$editSummary[] = 'tagging privileges ' . revoked($disableTagging);
|
|
}
|
|
if ($disableUpload != $cur['DisableUpload']) {
|
|
$set[] = "DisableUpload = ?";
|
|
$args[] = $disableUpload ? '1' : '0';
|
|
$privChange[] = 'Your upload privileges have been ' . revoked($disableUpload);
|
|
$editSummary[] = 'upload privileges ' . revoked($disableUpload);
|
|
}
|
|
if ($disableWiki != $cur['DisableWiki']) {
|
|
$set[] = "DisableWiki = ?";
|
|
$args[] = $disableWiki ? '1' : '0';
|
|
$privChange[] = 'Your site editing privileges have been ' . revoked($disableWiki);
|
|
$editSummary[] = 'wiki privileges ' . revoked($disableWiki);
|
|
}
|
|
if ($disablePM != $cur['DisablePM']) {
|
|
$set[] = "DisablePM = ?";
|
|
$args[] = $disablePM ? '1' : '0';
|
|
$privChange[] = 'Your private messate (PM) privileges have been ' . revoked($disablePM);
|
|
$editSummary[] = 'PM privileges ' . revoked($disablePM);
|
|
}
|
|
if ($disableRequests != $cur['DisableRequests']) {
|
|
$set[] = "DisableRequests = ?";
|
|
$args[] = $disableRequests ? '1' : '0';
|
|
$privChange[] = 'Your request privileges have been ' . revoked($disableRequests);
|
|
$editSummary[] = 'request privileges ' . revoked($disableRequests);
|
|
}
|
|
}
|
|
|
|
if (check_perms('users_disable_posts')) {
|
|
if ($disablePosting != $cur['DisablePosting']) {
|
|
$set[] = "DisablePosting = ?";
|
|
$args[] = $disablePosting ? '1' : '0';
|
|
$privChange[] = 'Your forum posting privileges have been ' . revoked($disablePosting);
|
|
$editSummary[] = 'posting privileges ' . revoked($disablePosting);
|
|
}
|
|
|
|
if ($disableForums != $cur['DisableForums']) {
|
|
$set[] = "DisableForums = ?";
|
|
$args[] = $disableForums ? '1' : '0';
|
|
$privChange[] = 'Your forum access has been ' . revoked($disableForums);
|
|
$editSummary[] = 'forums privileges ' . revoked($disableForums);
|
|
}
|
|
}
|
|
|
|
if ($disableIRC != $cur['DisableIRC']) {
|
|
$set[] = "DisableIRC = ?";
|
|
$args[] = $disableIRC ? '1' : '0';
|
|
$privChange[] = 'Your IRC privileges have been ' . revoked($disableIRC);
|
|
$editSummary[] = 'IRC privileges ' . revoked($disableIRC);
|
|
}
|
|
|
|
if ($privChange && $userReason) {
|
|
sort($privChange);
|
|
$userMan->sendPM(
|
|
$userId, 0,
|
|
count($privChange) == 1 ? $privChange[0] : 'Multiple privileges have changed on your account',
|
|
$Twig->render('user/pm-privilege.twig', [
|
|
'privs' => $privChange,
|
|
'reason' => $userReason,
|
|
'url' => 'wiki.php?action=article&id=5',
|
|
])
|
|
);
|
|
$editSummary[] = 'PM sent';
|
|
}
|
|
|
|
if ($enableUser != $cur['Enabled'] && check_perms('users_disable_users')) {
|
|
$enableStr = 'account ' . translateUserStatus($cur['Enabled']) . ' → ' . translateUserStatus($enableUser);
|
|
if ($enableUser == '2') {
|
|
$userMan->disableUserList([$userId], "Disabled via moderation", Gazelle\Manager\User::DISABLE_MANUAL);
|
|
$trackerUserUpdates = [];
|
|
} elseif ($enableUser == '1') {
|
|
$Cache->increment('stats_user_count');
|
|
$visibleTrIP = $visible && $cur['IP'] != '127.0.0.1' ? '1' : '0';
|
|
$tracker->update_tracker('add_user', ['id' => $userId, 'passkey' => $cur['torrent_pass'], 'visible' => $visibleTrIP]);
|
|
if (($cur['Downloaded'] == 0) || ($cur['Uploaded'] / $cur['Downloaded'] >= $cur['RequiredRatio'])) {
|
|
$canLeech = 1;
|
|
$set[] = "i.RatioWatchEnds = ?";
|
|
$args[] = null;
|
|
$set[] = "m.can_leech = ?";
|
|
$args[] = '1';
|
|
$set[] = "i.RatioWatchDownload = ?";
|
|
$args[] = '0';
|
|
} else {
|
|
$enableStr .= ' (Ratio: '.Format::get_ratio_html($cur['Uploaded'], $cur['Downloaded'], false).', RR: '.number_format($cur['RequiredRatio'],2).')';
|
|
if ($cur['RatioWatchEnds']) {
|
|
$set[] = "i.RatioWatchEnds = now()";
|
|
$set[] = "i.RatioWatchDownload = ?";
|
|
$args[] = $cur['Downloaded'];
|
|
$canLeech = 0;
|
|
}
|
|
$trackerUserUpdates['can_leech'] = 0;
|
|
}
|
|
$set[] = "i.BanReason = ?";
|
|
$args[] = '0';
|
|
$set[] = "Enabled = ?";
|
|
$args[] = '1';
|
|
}
|
|
$editSummary[] = $enableStr;
|
|
}
|
|
|
|
if (check_perms('users_edit_reset_keys')) {
|
|
if ($resetAuthkey == 1) {
|
|
$set[] = "Authkey = ?";
|
|
$args[] = randomString();
|
|
$editSummary[] = 'authkey reset';
|
|
}
|
|
if ($resetPasskey == 1) {
|
|
$passkey = randomString();
|
|
$user->modifyAnnounceKeyHistory($cur['torrent_pass'], $passkey, '0.0.0.0');
|
|
$Cache->delete_value('user_'.$cur['torrent_pass']);
|
|
$trackerUserUpdates['passkey'] = $passkey; // MUST come after the case for updating can_leech
|
|
$tracker->update_tracker('change_passkey', ['oldpasskey' => $cur['torrent_pass'], 'newpasskey' => $passkey]);
|
|
$set[] = "torrent_pass = ?";
|
|
$args[] = $passkey;
|
|
$editSummary[] = 'passkey reset';
|
|
}
|
|
}
|
|
|
|
if ($sendHackedMail && check_perms('users_disable_any')) {
|
|
(new Mail)->send($hackedEmail, 'Your ' . SITE_NAME . ' account',
|
|
$Twig->render('email/hacked.twig')
|
|
);
|
|
Tools::disable_users($userId, '', 1);
|
|
$editSummary[] = "hacked account email sent to $hackedEmail";
|
|
}
|
|
|
|
if ($mergeStatsFrom && check_perms('users_edit_ratio')) {
|
|
$stats = $user->mergeLeechStats($mergeStatsFrom, $LoggedUser['Username']);
|
|
if ($stats) {
|
|
$merge = new Gazelle\User($stats['userId']);
|
|
$merge->flush();
|
|
$leechSet[] = "Uploaded = Uploaded + ?";
|
|
$leechArgs[] = $stats['up'];
|
|
$leechSet[] = "Downloaded = Downloaded + ?";
|
|
$leechArgs[] = $stats['down'];
|
|
$editSummary[] = sprintf('leech stats (up: %s, down: %s, ratio: %s) merged from %s (%s) prior(up: %s, down: %s, ratio: %s)',
|
|
Format::get_size($stats['up']), Format::get_size($stats['down']), Format::get_ratio($stats['up'], $stats['down']),
|
|
$merge->url(), $mergeStatsFrom,
|
|
Format::get_size($cur['Uploaded']), Format::get_size($cur['Downloaded']),
|
|
Format::get_ratio($cur['Uploaded'], $cur['Downloaded'])
|
|
);
|
|
}
|
|
}
|
|
|
|
if ($changePassword && check_perms('users_edit_password')) {
|
|
$editSummary[] = 'password reset';
|
|
}
|
|
|
|
if (!(count($set) || count($leechSet) || count($editSummary)) && $reason) {
|
|
$editSummary[] = 'notes added';
|
|
}
|
|
|
|
// Because of the infinitely fucked up encoding/decoding of Gazelle, $adminComment !== $cur['AdminComment']
|
|
// almost always evaluates to true, even if the user did not purposely change the field. This then means
|
|
// we do have a bug where if a mod changes something about a user AND changes the admin comment, we will lose
|
|
// that change, but until we never decode stuff coming out of the DB, not much can be done.
|
|
|
|
if (count($editSummary)) {
|
|
$summary = implode(', ', $editSummary) . ' by ' . $LoggedUser['Username'];
|
|
$set[] = "AdminComment = ?";
|
|
$args[] = sqltime() . ' - ' . ucfirst($summary) . ($reason ? "\nReason: $reason" : '') . "\n\n$adminComment";
|
|
} elseif ($adminComment !== $cur['AdminComment']) {
|
|
$set[] = "AdminComment = ?";
|
|
$args[] = $adminComment;
|
|
}
|
|
|
|
if (!empty($set)) {
|
|
$args[] = $userId;
|
|
$DB->prepared_query("
|
|
UPDATE users_main AS m
|
|
INNER JOIN users_info AS i ON (m.ID = i.UserID)
|
|
SET " . implode(', ', $set) . "
|
|
WHERE m.ID = ?
|
|
", ...$args
|
|
);
|
|
}
|
|
|
|
if ($leechSet) {
|
|
$leechArgs[] = $userId;
|
|
$DB->prepared_query("
|
|
UPDATE users_leech_stats
|
|
SET " . implode(', ', $leechSet) . "
|
|
WHERE UserID = ?
|
|
", ...$leechArgs
|
|
);
|
|
}
|
|
|
|
if ($removedClasses) {
|
|
$user->removeClasses($removedClasses);
|
|
}
|
|
if ($addedClasses) {
|
|
$user->addClasses($addedClasses);
|
|
}
|
|
|
|
if ($changePassword && check_perms('users_edit_password')) {
|
|
$user->updatePassword($_POST['ChangePassword'], '127.0.0.1');
|
|
(new \Gazelle\Session($userId))->dropAll();
|
|
}
|
|
|
|
if ($newBonusPoints !== false) {
|
|
$bonus = new \Gazelle\Bonus;
|
|
$bonus->setPoints($userId, $newBonusPoints);
|
|
}
|
|
|
|
if ($flTokens != $cur['FLTokens']) {
|
|
$user->updateTokens($flTokens);
|
|
}
|
|
|
|
if (count($trackerUserUpdates) > 1) {
|
|
$tracker->update_tracker('update_user', $trackerUserUpdates);
|
|
}
|
|
|
|
if (count($set) || count($leechSet)) {
|
|
$user->flush();
|
|
}
|
|
|
|
if (isset($_POST['invite_source_update'])) {
|
|
$source = array_keys(array_filter($_POST, function ($x) { return preg_match('/^source-\d+$/', $x);}, ARRAY_FILTER_USE_KEY));
|
|
if ($source) {
|
|
$ids = [];
|
|
foreach ($source as $s) {
|
|
$ids[] = ((int)explode('-', $s)[1]);
|
|
}
|
|
(new Gazelle\Manager\InviteSource)->modifyInviterConfiguration($user->id(), $ids);
|
|
header("Location: tools.php?action=invite_source");
|
|
exit;
|
|
}
|
|
}
|
|
|
|
header("location: user.php?id=$userId");
|