Oppaitime's version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

takemoderate.php 35KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898
  1. <?
  2. /*************************************************************************\
  3. //--------------Take moderation -----------------------------------------//
  4. \*************************************************************************/
  5. // Are they being tricky blighters?
  6. if (!$_POST['userid'] || !is_number($_POST['userid'])) {
  7. error(404);
  8. } elseif (!check_perms('users_mod')) {
  9. error(403);
  10. }
  11. authorize();
  12. // End checking for moronity
  13. if (!apc_exists('DBKEY')) {
  14. error('Decrypt database first');
  15. }
  16. $UserID = $_POST['userid'];
  17. $DeleteKeys = false;
  18. // Variables for database input
  19. $Class = (int)$_POST['Class'];
  20. $Username = db_string($_POST['Username']);
  21. $Title = db_string($_POST['Title']);
  22. $AdminComment = db_string($_POST['AdminComment']);
  23. $Donor = isset($_POST['Donor']) ? 1 : 0;
  24. $Artist = isset($_POST['Artist']) ? 1 : 0;
  25. $SecondaryClasses = isset($_POST['secondary_classes']) ? $_POST['secondary_classes'] : array();
  26. foreach ($SecondaryClasses as $i => $Val) {
  27. if (!is_number($Val)) {
  28. unset($SecondaryClasses[$i]);
  29. }
  30. }
  31. $Visible = isset($_POST['Visible']) ? 1 : 0;
  32. $Invites = (int)$_POST['Invites'];
  33. $SupportFor = db_string($_POST['SupportFor']);
  34. $Pass = $_POST['ChangePassword'];
  35. $Warned = isset($_POST['Warned']) ? 1 : 0;
  36. if (isset($_POST['Uploaded']) && isset($_POST['Downloaded'])) {
  37. $Uploaded = ($_POST['Uploaded'] === '' ? 0 : $_POST['Uploaded']);
  38. if ($Arithmetic = strpbrk($Uploaded, '+-')) {
  39. $Uploaded += max(-$Uploaded, Format::get_bytes($Arithmetic));
  40. }
  41. $Downloaded = ($_POST['Downloaded'] === '' ? 0 : $_POST['Downloaded']);
  42. if ($Arithmetic = strpbrk($Downloaded, '+-')) {
  43. $Downloaded += max(-$Downloaded, Format::get_bytes($Arithmetic));
  44. }
  45. if (!is_number($Uploaded) || !is_number($Downloaded)) {
  46. error(0);
  47. }
  48. }
  49. $BonusPoints = isset($_POST['BonusPoints']) ? $_POST['BonusPoints'] : 0;
  50. if (!is_number($BonusPoints)) {
  51. error(0);
  52. }
  53. $FLTokens = isset($_POST['FLTokens']) ? $_POST['FLTokens'] : 0;
  54. if (!is_number($FLTokens)) {
  55. error(0);
  56. }
  57. $Badges = isset($_POST['badges']) ? $_POST['badges'] : array();
  58. $WarnLength = (int)$_POST['WarnLength'];
  59. $ExtendWarning = (int)$_POST['ExtendWarning'];
  60. $ReduceWarning = (int)$_POST['ReduceWarning'];
  61. $WarnReason = $_POST['WarnReason'];
  62. $UserReason = $_POST['UserReason'];
  63. $DisableAvatar = isset($_POST['DisableAvatar']) ? 1 : 0;
  64. $DisableInvites = isset($_POST['DisableInvites']) ? 1 : 0;
  65. $DisablePosting = isset($_POST['DisablePosting']) ? 1 : 0;
  66. $DisableForums = isset($_POST['DisableForums']) ? 1 : 0;
  67. $DisableTagging = isset($_POST['DisableTagging']) ? 1 : 0;
  68. $DisableUpload = isset($_POST['DisableUpload']) ? 1 : 0;
  69. $DisableWiki = isset($_POST['DisableWiki']) ? 1 : 0;
  70. $DisablePM = isset($_POST['DisablePM']) ? 1 : 0;
  71. $DisableNips = isset($_POST['DisableNips']) ? 1 : 0;
  72. $DisableIRC = isset($_POST['DisableIRC']) ? 1 : 0;
  73. $DisableRequests = isset($_POST['DisableRequests']) ? 1 : 0;
  74. $DisableLeech = isset($_POST['DisableLeech']) ? 0 : 1;
  75. $LockedAccount = isset($_POST['LockAccount']) ? 1 : 0;
  76. $LockType = $_POST['LockReason'];
  77. $RestrictedForums = db_string(trim($_POST['RestrictedForums']));
  78. $PermittedForums = db_string(trim($_POST['PermittedForums']));
  79. $EnableUser = (int)$_POST['UserStatus'];
  80. $ResetRatioWatch = isset($_POST['ResetRatioWatch']) ? 1 : 0;
  81. $ResetPasskey = isset($_POST['ResetPasskey']) ? 1 : 0;
  82. $ResetAuthkey = isset($_POST['ResetAuthkey']) ? 1 : 0;
  83. $SendHackedMail = isset($_POST['SendHackedMail']) ? 1 : 0;
  84. if ($SendHackedMail && !empty($_POST['HackedEmail'])) {
  85. $HackedEmail = $_POST['HackedEmail'];
  86. } else {
  87. $SendHackedMail = false;
  88. }
  89. $MergeStatsFrom = db_string($_POST['MergeStatsFrom']);
  90. $Reason = db_string($_POST['Reason']);
  91. $HeavyUpdates = array();
  92. $LightUpdates = array();
  93. // Get user info from the database
  94. $DB->query("
  95. SELECT
  96. m.Username,
  97. m.IP,
  98. m.Email,
  99. m.PermissionID,
  100. p.Level AS Class,
  101. m.Title,
  102. m.Enabled,
  103. m.Uploaded,
  104. m.Downloaded,
  105. m.Invites,
  106. m.can_leech,
  107. m.Visible,
  108. i.AdminComment,
  109. m.torrent_pass,
  110. i.Donor,
  111. i.Artist,
  112. i.Warned,
  113. i.SupportFor,
  114. i.RestrictedForums,
  115. i.PermittedForums,
  116. DisableAvatar,
  117. DisableInvites,
  118. DisablePosting,
  119. DisableForums,
  120. DisableTagging,
  121. DisableUpload,
  122. DisableWiki,
  123. DisablePM,
  124. DisableNips,
  125. DisableIRC,
  126. DisableRequests,
  127. m.RequiredRatio,
  128. m.FLTokens,
  129. m.BonusPoints,
  130. i.RatioWatchEnds,
  131. la.Type,
  132. SHA1(i.AdminComment) AS CommentHash,
  133. GROUP_CONCAT(l.PermissionID SEPARATOR ',') AS SecondaryClasses
  134. FROM users_main AS m
  135. JOIN users_info AS i ON i.UserID = m.ID
  136. LEFT JOIN permissions AS p ON p.ID = m.PermissionID
  137. LEFT JOIN users_levels AS l ON l.UserID = m.ID
  138. LEFT JOIN locked_accounts AS la ON la.UserID = m.ID
  139. WHERE m.ID = $UserID
  140. GROUP BY m.ID");
  141. if (!$DB->has_results()) { // If user doesn't exist
  142. header("Location: log.php?search=User+$UserID");
  143. }
  144. $Cur = $DB->next_record(MYSQLI_ASSOC, false);
  145. if ($_POST['comment_hash'] != $Cur['CommentHash']) {
  146. error("Somebody else has moderated this user since you loaded it. Please go back and refresh the page.");
  147. }
  148. //NOW that we know the class of the current user, we can see if one staff member is trying to hax0r us.
  149. if (!check_perms('users_mod', $Cur['Class'])) {
  150. //Son of a fucking bitch
  151. error(403);
  152. die();
  153. }
  154. if (!empty($_POST['donor_points_submit']) && !empty($_POST['donation_value']) && is_numeric($_POST['donation_value'])) {
  155. Donations::regular_donate($UserID, $_POST['donation_value'], "Add Points", $_POST['donation_reason'], $_POST['donation_currency']);
  156. } elseif (!empty($_POST['donor_values_submit'])) {
  157. Donations::update_rank($UserID, $_POST['donor_rank'], $_POST['total_donor_rank'], $_POST['reason']);
  158. }
  159. // If we're deleting the user, we can ignore all the other crap
  160. if ($_POST['UserStatus'] === 'delete' && check_perms('users_delete_users')) {
  161. Misc::write_log("User account $UserID (".$Cur['Username'].") was deleted by ".$LoggedUser['Username']);
  162. $DB->query("
  163. DELETE FROM users_main
  164. WHERE id = $UserID");
  165. $DB->query("
  166. DELETE FROM users_info
  167. WHERE UserID = $UserID");
  168. $Cache->delete_value("user_info_$UserID");
  169. Tracker::update_tracker('remove_user', array('passkey' => $Cur['torrent_pass']));
  170. header("Location: log.php?search=User+$UserID");
  171. die();
  172. }
  173. // User was not deleted. Perform other stuff.
  174. $UpdateSet = array();
  175. $EditSummary = array();
  176. $TrackerUserUpdates = array('passkey' => $Cur['torrent_pass']);
  177. $QueryID = G::$DB->get_query_id();
  178. if ($LockType == '---' || $LockedAccount == 0) {
  179. if ($Cur['Type']) {
  180. $DB->query("DELETE FROM locked_accounts WHERE UserID = '" . $UserID . "'");
  181. $EditSummary[] = 'Account unlocked';
  182. $Cache->delete_value('user_' . $Cur['torrent_pass']);
  183. }
  184. } else if (!$Cur['Type'] || $Cur['Type'] != $LockType) {
  185. $DB->query("INSERT INTO locked_accounts (UserID, Type)
  186. VALUES ('" . $UserID . "', '" . $LockType . "')
  187. ON DUPLICATE KEY UPDATE Type = '" . $LockType . "'");
  188. $Cache->delete_value('user_' . $Cur['torrent_pass']);
  189. if ($Cur['Type'] != $LockType) {
  190. $EditSummary[] = 'Account lock reason changed to ' . $LockType;
  191. } else {
  192. $EditSummary[] = 'Account locked (' . $LockType . ')';
  193. }
  194. }
  195. $Cache->delete_value("user_info_" . $UserID);
  196. $DB->set_query_id($QueryID);
  197. if ($_POST['ResetRatioWatch'] && check_perms('users_edit_reset_keys')) {
  198. $DB->query("
  199. UPDATE users_info
  200. SET RatioWatchEnds = '0000-00-00 00:00:00', RatioWatchDownload = '0', RatioWatchTimes = '0'
  201. WHERE UserID = '$UserID'");
  202. $EditSummary[] = 'RatioWatch history reset';
  203. }
  204. if ($_POST['ResetIPHistory'] && check_perms('users_edit_reset_keys')) {
  205. $GenericIP = DBCrypt::encrypt('127.0.0.1');
  206. $DB->query("
  207. DELETE FROM users_history_ips
  208. WHERE UserID = '$UserID'");
  209. $DB->query("
  210. UPDATE users_main
  211. SET IP = '$GenericIP'
  212. WHERE ID = '$UserID'");
  213. $DB->query("
  214. UPDATE xbt_snatched
  215. SET IP = ''
  216. WHERE uid = '$UserID'");
  217. $DB->query("
  218. UPDATE users_history_passwords
  219. SET ChangerIP = ''
  220. WHERE UserID = $UserID");
  221. $DB->query("
  222. UPDATE users_history_passkeys
  223. SET ChangerIP = ''
  224. WHERE UserID = $UserID");
  225. $DB->query("
  226. UPDATE users_sessions
  227. SET IP = '$GenericIP'
  228. WHERE UserID = $UserID");
  229. }
  230. if ($_POST['ResetEmailHistory'] && check_perms('users_edit_reset_keys')) {
  231. $DB->query("
  232. DELETE FROM users_history_emails
  233. WHERE UserID = '$UserID'");
  234. if ($_POST['ResetIPHistory']) {
  235. $DB->query("
  236. INSERT INTO users_history_emails
  237. (UserID, Email, Time, IP)
  238. VALUES
  239. ('$UserID', '".DBCrypt::encrypt($Username.'@'.SITE_DOMAIN)."', '0000-00-00 00:00:00', '".DBCrypt::encrypt('127.0.0.1')."')");
  240. } else {
  241. $DB->query("
  242. INSERT INTO users_history_emails
  243. (UserID, Email, Time, IP)
  244. VALUES
  245. ('$UserID', '".DBCrypt::encrypt($Username.'@'.SITE_DOMAIN)."', '0000-00-00 00:00:00', '".$Cur['IP']."')");
  246. }
  247. $DB->query("
  248. UPDATE users_main
  249. SET Email = '".DBCrypt::encrypt($Username.'@'.SITE_DOMAIN)."'
  250. WHERE ID = '$UserID'");
  251. $EditSummary[] = 'Email history cleared';
  252. }
  253. if ($_POST['ResetSnatchList'] && check_perms('users_edit_reset_keys')) {
  254. $DB->query("
  255. DELETE FROM xbt_snatched
  256. WHERE uid = '$UserID'");
  257. $EditSummary[] = 'Snatch list cleared';
  258. $Cache->delete_value("recent_snatches_$UserID");
  259. }
  260. if ($_POST['ResetDownloadList'] && check_perms('users_edit_reset_keys')) {
  261. $DB->query("
  262. DELETE FROM users_downloads
  263. WHERE UserID = '$UserID'");
  264. $EditSummary[] = 'Download list cleared';
  265. }
  266. if (($_POST['ResetSession'] || $_POST['LogOut']) && check_perms('users_logout')) {
  267. $Cache->delete_value("user_info_$UserID");
  268. $Cache->delete_value("user_info_heavy_$UserID");
  269. $Cache->delete_value("user_stats_$UserID");
  270. $Cache->delete_value("enabled_$UserID");
  271. if ($_POST['LogOut']) {
  272. $DB->query("
  273. SELECT SessionID
  274. FROM users_sessions
  275. WHERE UserID = '$UserID'");
  276. while (list($SessionID) = $DB->next_record()) {
  277. $Cache->delete_value("session_{$UserID}_$SessionID");
  278. }
  279. $Cache->delete_value("users_sessions_$UserID");
  280. $DB->query("
  281. DELETE FROM users_sessions
  282. WHERE UserID = '$UserID'");
  283. }
  284. }
  285. // Start building SQL query and edit summary
  286. if ($Classes[$Class]['Level'] != $Cur['Class']
  287. && (
  288. ($Classes[$Class]['Level'] < $LoggedUser['Class'] && check_perms('users_promote_below', $Cur['Class']))
  289. || ($Classes[$Class]['Level'] <= $LoggedUser['Class'] && check_perms('users_promote_to', $Cur['Class'] - 1))
  290. )
  291. ) {
  292. $UpdateSet[] = "PermissionID = '$Class'";
  293. $EditSummary[] = 'class changed to '.Users::make_class_string($Class);
  294. $LightUpdates['PermissionID'] = $Class;
  295. $DeleteKeys = true;
  296. $DB->query("
  297. SELECT DISTINCT DisplayStaff
  298. FROM permissions
  299. WHERE ID = $Class
  300. OR ID = ".$ClassLevels[$Cur['Class']]['ID']);
  301. if ($DB->record_count() === 2) {
  302. if ($Classes[$Class]['Level'] < $Cur['Class']) {
  303. $SupportFor = '';
  304. }
  305. $ClearStaffIDCache = true;
  306. }
  307. $Cache->delete_value("donor_info_$UserID");
  308. }
  309. if ($Username != $Cur['Username'] && check_perms('users_edit_usernames', $Cur['Class'] - 1)) {
  310. $DB->query("
  311. SELECT ID
  312. FROM users_main
  313. WHERE Username = '$Username'");
  314. if ($DB->next_record() > 0) {
  315. list($UsedUsernameID) = $DB->next_record();
  316. error("Username already in use by <a href=\"user.php?id=$UsedUsernameID\">$Username</a>");
  317. header("Location: user.php?id=$UserID");
  318. die();
  319. } elseif ($Username == '0' || $Username == '1') {
  320. error('You cannot set a username of "0" or "1".');
  321. header("Location: user.php?id=$UserID");
  322. die();
  323. } else {
  324. $UpdateSet[] = "Username = '$Username'";
  325. $EditSummary[] = "username changed from ".$Cur['Username']." to $Username";
  326. $LightUpdates['Username'] = $Username;
  327. }
  328. }
  329. if ($Title != db_string($Cur['Title']) && check_perms('users_edit_titles')) {
  330. // Using the unescaped value for the test to avoid confusion
  331. if (strlen($_POST['Title']) > 1024) {
  332. error("Custom titles have a maximum length of 1,024 characters.");
  333. header("Location: user.php?id=$UserID");
  334. die();
  335. } else {
  336. $UpdateSet[] = "Title = '$Title'";
  337. $EditSummary[] = "title changed to [code]{$Title}[/code]";
  338. $LightUpdates['Title'] = $_POST['Title'];
  339. }
  340. }
  341. if ($Donor != $Cur['Donor'] && check_perms('users_give_donor')) {
  342. $UpdateSet[] = "Donor = '$Donor'";
  343. $EditSummary[] = 'donor status changed';
  344. $LightUpdates['Donor'] = $Donor;
  345. }
  346. // Secondary classes
  347. $OldClasses = $Cur['SecondaryClasses'] ? explode(',', $Cur['SecondaryClasses']) : array();
  348. $DroppedClasses = array_diff($OldClasses, $SecondaryClasses);
  349. $AddedClasses = array_diff($SecondaryClasses, $OldClasses);
  350. if (count($DroppedClasses) > 0) {
  351. $ClassChanges = array();
  352. foreach ($DroppedClasses as $PermID) {
  353. $ClassChanges[] = $Classes[$PermID]['Name'];
  354. }
  355. $EditSummary[] = 'Secondary classes dropped: '.implode(', ', $ClassChanges);
  356. $DB->query("
  357. DELETE FROM users_levels
  358. WHERE UserID = '$UserID'
  359. AND PermissionID IN (".implode(',', $DroppedClasses).')');
  360. if (count($SecondaryClasses) > 0) {
  361. $LightUpdates['ExtraClasses'] = array_fill_keys($SecondaryClasses, 1);
  362. } else {
  363. $LightUpdates['ExtraClasses'] = array();
  364. }
  365. $DeleteKeys = true;
  366. }
  367. if (count($AddedClasses) > 0) {
  368. $ClassChanges = array();
  369. foreach ($AddedClasses as $PermID) {
  370. $ClassChanges[] = $Classes[$PermID]['Name'];
  371. }
  372. $EditSummary[] = "Secondary classes added: ".implode(', ', $ClassChanges);
  373. $Values = array();
  374. foreach ($AddedClasses as $PermID) {
  375. $Values[] = "($UserID, $PermID)";
  376. }
  377. $DB->query("
  378. INSERT INTO users_levels (UserID, PermissionID)
  379. VALUES ".implode(', ', $Values));
  380. //$LightUpdates['ExtraClasses'] = array_fill_keys($SecondaryClasses, 1);
  381. $DeleteKeys = true;
  382. }
  383. if ($Visible != $Cur['Visible'] && check_perms('users_make_invisible')) {
  384. $UpdateSet[] = "Visible = '$Visible'";
  385. $EditSummary[] = 'visibility changed';
  386. $LightUpdates['Visible'] = $Visible;
  387. $TrackerUserUpdates['visible'] = $Visible;
  388. }
  389. if ($Uploaded != $Cur['Uploaded'] && $Uploaded != $_POST['OldUploaded'] && (check_perms('users_edit_ratio')
  390. || (check_perms('users_edit_own_ratio') && $UserID == $LoggedUser['ID']))) {
  391. $UpdateSet[] = "Uploaded = '$Uploaded'";
  392. $EditSummary[] = "uploaded changed from ".Format::get_size($Cur['Uploaded']).' to '.Format::get_size($Uploaded);
  393. $Cache->delete_value("user_stats_$UserID");
  394. }
  395. if ($Downloaded != $Cur['Downloaded'] && $Downloaded != $_POST['OldDownloaded'] && (check_perms('users_edit_ratio')
  396. || (check_perms('users_edit_own_ratio') && $UserID == $LoggedUser['ID']))) {
  397. $UpdateSet[] = "Downloaded = '$Downloaded'";
  398. $EditSummary[] = "downloaded changed from ".Format::get_size($Cur['Downloaded']).' to '.Format::get_size($Downloaded);
  399. $Cache->delete_value("user_stats_$UserID");
  400. }
  401. if ($BonusPoints != $Cur['BonusPoints'] && (check_perms('users_edit_ratio') || (check_perms('users_edit_own_ratio') && $UserID == $LoggedUser['ID']))) {
  402. $UpdateSet[] = "BonusPoints = $BonusPoints";
  403. $EditSummary[] = "Bonus Points changed from ".$Cur['BonusPoints']." to $BonusPoints";
  404. $HeavyUpdates['BonusPoints'] = $BonusPoints;
  405. }
  406. if ($FLTokens != $Cur['FLTokens'] && (check_perms('users_edit_ratio') || (check_perms('users_edit_own_ratio') && $UserID == $LoggedUser['ID']))) {
  407. $UpdateSet[] = "FLTokens = $FLTokens";
  408. $EditSummary[] = "Freeleech Tokens changed from ".$Cur['FLTokens']." to $FLTokens";
  409. $HeavyUpdates['FLTokens'] = $FLTokens;
  410. }
  411. if ($Invites != $Cur['Invites'] && check_perms('users_edit_invites')) {
  412. $UpdateSet[] = "invites = '$Invites'";
  413. $EditSummary[] = "number of invites changed to $Invites";
  414. $HeavyUpdates['Invites'] = $Invites;
  415. }
  416. if (check_perms('users_edit_badges')) {
  417. $query = "DELETE FROM users_badges WHERE UserID = $UserID";
  418. if (!empty($Badges)) {
  419. $query .= " AND BadgeID NOT IN (".implode(',', $Badges).")";
  420. }
  421. $DB->query($query);
  422. if (!empty ($Badges)) {
  423. $query = "INSERT IGNORE INTO users_badges (UserID, BadgeID) VALUES ";
  424. $len = count($Badges);
  425. foreach ($Badges AS $i => $BadgeID) {
  426. $query .= "($UserID, $BadgeID)";
  427. if ($i < ($len-1))
  428. $query .= ", ";
  429. }
  430. $DB->query($query);
  431. }
  432. $Cache->delete_value("user_badges_".$UserID);
  433. }
  434. if ($Warned == 1 && $Cur['Warned'] == '0000-00-00 00:00:00' && check_perms('users_warn')) {
  435. $Weeks = 'week' . ($WarnLength === 1 ? '' : 's');
  436. Misc::send_pm($UserID, 0, 'You have received a warning', "You have been [url=".site_url()."wiki.php?action=article&amp;id=218]warned for $WarnLength {$Weeks}[/url] by [user]".$LoggedUser['Username']."[/user]. The reason given was:
  437. [quote]{$WarnReason}[/quote]");
  438. $UpdateSet[] = "Warned = '".sqltime()."' + INTERVAL $WarnLength WEEK";
  439. $Msg = "warned for $WarnLength $Weeks";
  440. if ($WarnReason) {
  441. $Msg .= " for \"$WarnReason\"";
  442. }
  443. $EditSummary[] = db_string($Msg);
  444. $LightUpdates['Warned'] = time_plus(3600 * 24 * 7 * $WarnLength);
  445. } elseif ($Warned == 0 && $Cur['Warned'] != '0000-00-00 00:00:00' && check_perms('users_warn')) {
  446. $UpdateSet[] = "Warned = '0000-00-00 00:00:00'";
  447. $EditSummary[] = 'warning removed';
  448. $LightUpdates['Warned'] = '0000-00-00 00:00:00';
  449. } elseif ($Warned == 1 && $ExtendWarning != '---' && check_perms('users_warn')) {
  450. $Weeks = 'week' . ($ExtendWarning === 1 ? '' : 's');
  451. Misc::send_pm($UserID, 0, 'Your warning has been extended', "Your warning has been extended by $ExtendWarning $Weeks by [user]".$LoggedUser['Username']."[/user]. The reason given was:
  452. [quote]{$WarnReason}[/quote]");
  453. $UpdateSet[] = "Warned = Warned + INTERVAL $ExtendWarning WEEK";
  454. $DB->query("
  455. SELECT Warned + INTERVAL $ExtendWarning WEEK
  456. FROM users_info
  457. WHERE UserID = '$UserID'");
  458. list($WarnedUntil) = $DB->next_record();
  459. $Msg = "warning extended by $ExtendWarning $Weeks to $WarnedUntil";
  460. if ($WarnReason) {
  461. $Msg .= " for \"$WarnReason\"";
  462. }
  463. $EditSummary[] = db_string($Msg);
  464. $LightUpdates['Warned'] = $WarnedUntil;
  465. } elseif ($Warned == 1 && $ExtendWarning == '---' && $ReduceWarning != '---' && check_perms('users_warn')) {
  466. $Weeks = 'week' . ($ReduceWarning === 1 ? '' : 's');
  467. Misc::send_pm($UserID, 0, 'Your warning has been reduced', "Your warning has been reduced by $ReduceWarning $Weeks by [user]".$LoggedUser['Username']."[/user]. The reason given was:
  468. [quote]{$WarnReason}[/quote]");
  469. $UpdateSet[] = "Warned = Warned - INTERVAL $ReduceWarning WEEK";
  470. $DB->query("
  471. SELECT Warned - INTERVAL $ReduceWarning WEEK
  472. FROM users_info
  473. WHERE UserID = '$UserID'");
  474. list($WarnedUntil) = $DB->next_record();
  475. $Msg = "warning reduced by $ReduceWarning $Weeks to $WarnedUntil";
  476. if ($WarnReason) {
  477. $Msg .= " for \"$WarnReason\"";
  478. }
  479. $EditSummary[] = db_string($Msg);
  480. $LightUpdates['Warned'] = $WarnedUntil;
  481. }
  482. if ($SupportFor != db_string($Cur['SupportFor']) && (check_perms('admin_manage_fls') || (check_perms('users_mod') && $UserID == $LoggedUser['ID']))) {
  483. $UpdateSet[] = "SupportFor = '$SupportFor'";
  484. $EditSummary[] = "First-Line Support status changed to \"$SupportFor\"";
  485. }
  486. if ($RestrictedForums != db_string($Cur['RestrictedForums']) && check_perms('users_mod')) {
  487. $UpdateSet[] = "RestrictedForums = '$RestrictedForums'";
  488. $EditSummary[] = "restricted forum(s): $RestrictedForums";
  489. $DeleteKeys = true;
  490. }
  491. if ($PermittedForums != db_string($Cur['PermittedForums']) && check_perms('users_mod')) {
  492. $ForumSet = explode(',', $PermittedForums);
  493. $ForumList = array();
  494. foreach ($ForumSet as $ForumID) {
  495. if ($Forums[$ForumID]['MinClassCreate'] <= $LoggedUser['EffectiveClass']) {
  496. $ForumList[] = $ForumID;
  497. }
  498. }
  499. $PermittedForums = implode(',', $ForumSet);
  500. $UpdateSet[] = "PermittedForums = '$PermittedForums'";
  501. $EditSummary[] = "permitted forum(s): $PermittedForums";
  502. $DeleteKeys = true;
  503. }
  504. if ($DisableAvatar != $Cur['DisableAvatar'] && check_perms('users_disable_any')) {
  505. $UpdateSet[] = "DisableAvatar = '$DisableAvatar'";
  506. $EditSummary[] = 'avatar privileges ' . ($DisableAvatar ? 'disabled' : 'enabled');
  507. $HeavyUpdates['DisableAvatar'] = $DisableAvatar;
  508. if (!empty($UserReason)) {
  509. Misc::send_pm($UserID, 0, 'Your avatar privileges have been disabled', "Your avatar privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  510. }
  511. }
  512. if ($DisableLeech != $Cur['can_leech'] && check_perms('users_disable_any')) {
  513. $UpdateSet[] = "can_leech = '$DisableLeech'";
  514. $EditSummary[] = "leeching status changed (".translateLeechStatus($Cur['can_leech'])." -> ".translateLeechStatus($DisableLeech).")";
  515. $HeavyUpdates['DisableLeech'] = $DisableLeech;
  516. $HeavyUpdates['CanLeech'] = $DisableLeech;
  517. if (!empty($UserReason)) {
  518. Misc::send_pm($UserID, 0, 'Your leeching privileges have been disabled', "Your leeching privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  519. }
  520. $TrackerUserUpdates['can_leech'] = $DisableLeech;
  521. }
  522. if ($DisableInvites != $Cur['DisableInvites'] && check_perms('users_disable_any')) {
  523. $UpdateSet[] = "DisableInvites = '$DisableInvites'";
  524. if ($DisableInvites == 1) {
  525. //$UpdateSet[] = "Invites = '0'";
  526. if (!empty($UserReason)) {
  527. Misc::send_pm($UserID, 0, 'Your invite privileges have been disabled', "Your invite privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  528. }
  529. }
  530. $EditSummary[] = 'invites privileges ' . ($DisableInvites ? 'disabled' : 'enabled');
  531. $HeavyUpdates['DisableInvites'] = $DisableInvites;
  532. }
  533. if ($DisablePosting != $Cur['DisablePosting'] && check_perms('users_disable_posts')) {
  534. $UpdateSet[] = "DisablePosting = '$DisablePosting'";
  535. $EditSummary[] = 'posting privileges ' . ($DisablePosting ? 'disabled' : 'enabled');
  536. $HeavyUpdates['DisablePosting'] = $DisablePosting;
  537. if (!empty($UserReason)) {
  538. Misc::send_pm($UserID, 0, 'Your forum posting privileges have been disabled', "Your forum posting privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  539. }
  540. }
  541. if ($DisableForums != $Cur['DisableForums'] && check_perms('users_disable_posts')) {
  542. $UpdateSet[] = "DisableForums = '$DisableForums'";
  543. $EditSummary[] = 'forums privileges ' . ($DisableForums ? 'disabled' : 'enabled');
  544. $HeavyUpdates['DisableForums'] = $DisableForums;
  545. if (!empty($UserReason)) {
  546. Misc::send_pm($UserID, 0, 'Your forum privileges have been disabled', "Your forum privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  547. }
  548. }
  549. if ($DisableTagging != $Cur['DisableTagging'] && check_perms('users_disable_any')) {
  550. $UpdateSet[] = "DisableTagging = '$DisableTagging'";
  551. $EditSummary[] = 'tagging privileges ' . ($DisableTagging ? 'disabled' : 'enabled');
  552. $HeavyUpdates['DisableTagging'] = $DisableTagging;
  553. if (!empty($UserReason)) {
  554. Misc::send_pm($UserID, 0, 'Your tagging privileges have been disabled', "Your tagging privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  555. }
  556. }
  557. if ($DisableUpload != $Cur['DisableUpload'] && check_perms('users_disable_any')) {
  558. $UpdateSet[] = "DisableUpload = '$DisableUpload'";
  559. $EditSummary[] = 'upload privileges ' . ($DisableUpload ? 'disabled' : 'enabled');
  560. $HeavyUpdates['DisableUpload'] = $DisableUpload;
  561. if ($DisableUpload == 1) {
  562. Misc::send_pm($UserID, 0, 'Your upload privileges have been disabled', "Your upload privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  563. }
  564. }
  565. if ($DisableWiki != $Cur['DisableWiki'] && check_perms('users_disable_any')) {
  566. $UpdateSet[] = "DisableWiki = '$DisableWiki'";
  567. $EditSummary[] = 'wiki privileges ' . ($DisableWiki ? 'disabled' : 'enabled');
  568. $HeavyUpdates['DisableWiki'] = $DisableWiki;
  569. $HeavyUpdates['site_edit_wiki'] = 0;
  570. if (!empty($UserReason)) {
  571. Misc::send_pm($UserID, 0, 'Your site editing privileges have been disabled', "Your site editing privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  572. }
  573. }
  574. if ($DisablePM != $Cur['DisablePM'] && check_perms('users_disable_any')) {
  575. $UpdateSet[] = "DisablePM = '$DisablePM'";
  576. $EditSummary[] = 'PM privileges ' . ($DisablePM ? 'disabled' : 'enabled');
  577. $HeavyUpdates['DisablePM'] = $DisablePM;
  578. if (!empty($UserReason)) {
  579. Misc::send_pm($UserID, 0, 'Your PM privileges have been disabled', "Your PM privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  580. }
  581. }
  582. if ($DisableNips != $Cur['DisableNips'] && check_perms('users_disable_any')) {
  583. $UpdateSet[] = "DisableNips = '$DisableNips'";
  584. $EditSummary[] = 'Nip earning ' . ($DisableNips ? 'disabled' : 'enabled');
  585. $HeavyUpdates['DisableNips'] = $DisableNips;
  586. if (!empty($UserReason)) {
  587. Misc::send_pm($UserID, 0, 'Your Nip-earning ability has been disabled', "Your Nip-earning ability been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  588. }
  589. }
  590. if ($DisableIRC != $Cur['DisableIRC'] && check_perms('users_disable_any')) {
  591. $UpdateSet[] = "DisableIRC = '$DisableIRC'";
  592. $EditSummary[] = 'IRC privileges ' . ($DisableIRC ? 'disabled' : 'enabled');
  593. $HeavyUpdates['DisableIRC'] = $DisableIRC;
  594. if (!empty($UserReason)) {
  595. Misc::send_pm($UserID, 0, 'Your IRC privileges have been disabled', "Your IRC privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url]. This loss of privileges does not affect the ability to join and talk to staff in '.BOT_DISABLED_CHAN.'.');
  596. }
  597. }
  598. if ($DisableRequests != $Cur['DisableRequests'] && check_perms('users_disable_any')) {
  599. $UpdateSet[] = "DisableRequests = '$DisableRequests'";
  600. $EditSummary[] = 'request privileges ' . ($DisableRequests ? 'disabled' : 'enabled');
  601. $HeavyUpdates['DisableRequests'] = $DisableRequests;
  602. if (!empty($UserReason)) {
  603. Misc::send_pm($UserID, 0, 'Your request privileges have been disabled', "Your request privileges have been disabled. The reason given was: [quote]{$UserReason}[/quote] If you would like to discuss this, please join ".BOT_DISABLED_CHAN.' on our IRC network. Instructions can be found [url='.site_url().'wiki.php?action=article&amp;name=IRC+-+How+to+join]here[/url].');
  604. }
  605. }
  606. if ($EnableUser != $Cur['Enabled'] && check_perms('users_disable_users')) {
  607. $EnableStr = 'account '.translateUserStatus($Cur['Enabled']).'->'.translateUserStatus($EnableUser);
  608. if ($EnableUser == '2') {
  609. Tools::disable_users($UserID, '', 1);
  610. $TrackerUserUpdates = array();
  611. } elseif ($EnableUser == '1') {
  612. $Cache->increment('stats_user_count');
  613. $VisibleTrIP = ($Visible && DBCrypt::decrypt($Cur['IP']) != '127.0.0.1') ? '1' : '0';
  614. Tracker::update_tracker('add_user', array('id' => $UserID, 'passkey' => $Cur['torrent_pass'], 'visible' => $VisibleTrIP));
  615. if (($Cur['Downloaded'] == 0) || ($Cur['Uploaded'] / $Cur['Downloaded'] >= $Cur['RequiredRatio'])) {
  616. $UpdateSet[] = "i.RatioWatchEnds = '0000-00-00 00:00:00'";
  617. $CanLeech = 1;
  618. $UpdateSet[] = "m.can_leech = '1'";
  619. $UpdateSet[] = "i.RatioWatchDownload = '0'";
  620. } else {
  621. $EnableStr .= ' (Ratio: '.Format::get_ratio_html($Cur['Uploaded'], $Cur['Downloaded'], false).', RR: '.number_format($Cur['RequiredRatio'],2).')';
  622. if ($Cur['RatioWatchEnds'] != '0000-00-00 00:00:00') {
  623. $UpdateSet[] = "i.RatioWatchEnds = NOW()";
  624. $UpdateSet[] = "i.RatioWatchDownload = m.Downloaded";
  625. $CanLeech = 0;
  626. }
  627. $TrackerUserUpdates['can_leech'] = 0;
  628. }
  629. $UpdateSet[] = "i.BanReason = '0'";
  630. $UpdateSet[] = "Enabled = '1'";
  631. $LightUpdates['Enabled'] = 1;
  632. }
  633. $EditSummary[] = $EnableStr;
  634. $Cache->replace_value("enabled_$UserID", $EnableUser, 0);
  635. }
  636. if ($ResetPasskey == 1 && check_perms('users_edit_reset_keys')) {
  637. $Passkey = db_string(Users::make_secret());
  638. $UpdateSet[] = "torrent_pass = '$Passkey'";
  639. $EditSummary[] = 'passkey reset';
  640. $HeavyUpdates['torrent_pass'] = $Passkey;
  641. $TrackerUserUpdates['passkey'] = $Passkey;
  642. $Cache->delete_value('user_'.$Cur['torrent_pass']);
  643. //MUST come after the case for updating can_leech.
  644. $DB->query("
  645. INSERT INTO users_history_passkeys
  646. (UserID, OldPassKey, NewPassKey, ChangerIP, ChangeTime)
  647. VALUES
  648. ('$UserID', '".$Cur['torrent_pass']."', '$Passkey', '".DBCrypt::encrypt('0.0.0.0')."', '".sqltime()."')");
  649. Tracker::update_tracker('change_passkey', array('oldpasskey' => $Cur['torrent_pass'], 'newpasskey' => $Passkey));
  650. }
  651. if ($ResetAuthkey == 1 && check_perms('users_edit_reset_keys')) {
  652. $Authkey = db_string(Users::make_secret());
  653. $UpdateSet[] = "AuthKey = '$Authkey'";
  654. $EditSummary[] = 'authkey reset';
  655. $HeavyUpdates['AuthKey'] = $Authkey;
  656. }
  657. if ($SendHackedMail && check_perms('users_disable_any')) {
  658. $EditSummary[] = "hacked account email sent to $HackedEmail";
  659. Misc::send_email($HackedEmail, 'Your '.SITE_NAME.' account', 'Your '.SITE_NAME.' account appears to have been compromised. As a security measure, we have disabled your account. To resolve this, please visit us on IRC.
  660. This is the information to connect to our server:
  661. IRC Server: '.BOT_SERVER.'
  662. Port: '.BOT_PORT.' ('.BOT_PORT_SSL.' for SSL)
  663. Once you are connected to our server you will need to join our disabled users channel.
  664. Type: /join '.BOT_DISABLED_CHAN.'
  665. Please visit us soon so we can help you resolve this matter.');
  666. }
  667. if ($MergeStatsFrom && check_perms('users_edit_ratio')) {
  668. $DB->query("
  669. SELECT ID, Uploaded, Downloaded
  670. FROM users_main
  671. WHERE Username LIKE '$MergeStatsFrom'");
  672. if ($DB->has_results()) {
  673. list($MergeID, $MergeUploaded, $MergeDownloaded) = $DB->next_record();
  674. $DB->query("
  675. UPDATE users_main AS um
  676. JOIN users_info AS ui ON um.ID = ui.UserID
  677. SET
  678. um.Uploaded = 0,
  679. um.Downloaded = 0,
  680. ui.AdminComment = CONCAT('".sqltime().' - Stats (Uploaded: '.Format::get_size($MergeUploaded).', Downloaded: '.Format::get_size($MergeDownloaded).', Ratio: '.Format::get_ratio($MergeUploaded, $MergeDownloaded).') merged into '.site_url()."user.php?id=$UserID (".$Cur['Username'].') by '.$LoggedUser['Username']."\n\n', ui.AdminComment)
  681. WHERE ID = $MergeID");
  682. $UpdateSet[] = "Uploaded = Uploaded + '$MergeUploaded'";
  683. $UpdateSet[] = "Downloaded = Downloaded + '$MergeDownloaded'";
  684. $EditSummary[] = 'stats merged from '.site_url()."user.php?id=$MergeID ($MergeStatsFrom) (previous stats: Uploaded: ".Format::get_size($Cur['Uploaded']).', Downloaded: '.Format::get_size($Cur['Downloaded']).', Ratio: '.Format::get_ratio($Cur['Uploaded'], $Cur['Downloaded']).')';
  685. $Cache->delete_value("user_stats_$UserID");
  686. $Cache->delete_value("user_stats_$MergeID");
  687. }
  688. }
  689. if ($Pass && check_perms('users_edit_password')) {
  690. $UpdateSet[] = "PassHash = '".db_string(Users::make_sec_hash($Pass))."'";
  691. $EditSummary[] = 'password reset';
  692. $Cache->delete_value("user_info_$UserID");
  693. $Cache->delete_value("user_info_heavy_$UserID");
  694. $Cache->delete_value("user_stats_$UserID");
  695. $Cache->delete_value("enabled_$UserID");
  696. $DB->query("
  697. SELECT SessionID
  698. FROM users_sessions
  699. WHERE UserID = '$UserID'");
  700. while (list($SessionID) = $DB->next_record()) {
  701. $Cache->delete_value("session_{$UserID}_$SessionID");
  702. }
  703. $Cache->delete_value("users_sessions_$UserID");
  704. $DB->query("
  705. DELETE FROM users_sessions
  706. WHERE UserID = '$UserID'");
  707. }
  708. if (empty($UpdateSet) && empty($EditSummary)) {
  709. if (!$Reason) {
  710. if (str_replace("\r", '', $Cur['AdminComment']) != str_replace("\r", '', $AdminComment) && check_perms('users_disable_any')) {
  711. $UpdateSet[] = "AdminComment = '$AdminComment'";
  712. } else {
  713. header("Location: user.php?id=$UserID");
  714. die();
  715. }
  716. } else {
  717. $EditSummary[] = 'notes added';
  718. }
  719. }
  720. if (count($TrackerUserUpdates) > 1) {
  721. Tracker::update_tracker('update_user', $TrackerUserUpdates);
  722. }
  723. if ($DeleteKeys) {
  724. $Cache->delete_value("user_info_$UserID");
  725. $Cache->delete_value("user_info_heavy_$UserID");
  726. } else {
  727. $Cache->begin_transaction("user_info_$UserID");
  728. $Cache->update_row(false, $LightUpdates);
  729. $Cache->commit_transaction(0);
  730. $Cache->begin_transaction("user_info_heavy_$UserID");
  731. $Cache->update_row(false, $HeavyUpdates);
  732. $Cache->commit_transaction(0);
  733. }
  734. $Summary = '';
  735. // Create edit summary
  736. if ($EditSummary) {
  737. $Summary = implode(', ', $EditSummary) . ' by ' . $LoggedUser['Username'];
  738. $Summary = sqltime() . ' - ' . ucfirst($Summary);
  739. if ($Reason) {
  740. $Summary .= "\nReason: $Reason";
  741. }
  742. $Summary .= "\n\n$AdminComment";
  743. } elseif (empty($UpdateSet) && empty($EditSummary) && $Cur['AdminComment'] == $_POST['AdminComment']) {
  744. $Summary = sqltime() . ' - Comment added by ' . $LoggedUser['Username'] . ': ' . "$Reason\n\n";
  745. }
  746. if (!empty($Summary)) {
  747. $UpdateSet[] = "AdminComment = '$Summary'";
  748. } else {
  749. $UpdateSet[] = "AdminComment = '$AdminComment'";
  750. }
  751. // Update cache
  752. // Build query
  753. $SET = implode(', ', $UpdateSet);
  754. $SQL = "
  755. UPDATE users_main AS m
  756. JOIN users_info AS i ON m.ID = i.UserID
  757. SET $SET
  758. WHERE m.ID = '$UserID'";
  759. // Perform update
  760. //die($SQL);
  761. $DB->query($SQL);
  762. if (isset($ClearStaffIDCache)) {
  763. $Cache->delete_value('staff_ids');
  764. }
  765. // redirect to user page
  766. header("location: user.php?id=$UserID");
  767. function translateUserStatus($Status) {
  768. switch ($Status) {
  769. case 0:
  770. return 'Unconfirmed';
  771. case 1:
  772. return 'Enabled';
  773. case 2:
  774. return 'Disabled';
  775. default:
  776. return $Status;
  777. }
  778. }
  779. function translateLeechStatus($Status) {
  780. switch ($Status) {
  781. case 0:
  782. return 'Disabled';
  783. case 1:
  784. return 'Enabled';
  785. default:
  786. return $Status;
  787. }
  788. }
  789. ?>