BioTorrents.de’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.

advancedsearch.php 40KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  1. <?php
  2. #declare(strict_types = 1);
  3. $ENV = ENV::go();
  4. if (!empty($_GET['search'])) {
  5. if (preg_match('/^'.$ENV->IP_REGEX.'$/', $_GET['search'])) {
  6. $_GET['ip'] = $_GET['search'];
  7. } elseif (preg_match('/^'.EMAIL_REGEX.'$/i', $_GET['search'])) {
  8. $_GET['email'] = $_GET['search'];
  9. } elseif (preg_match(USERNAME_REGEX, $_GET['search'])) {
  10. $DB->query("
  11. SELECT ID
  12. FROM users_main
  13. WHERE Username = '".db_string($_GET['search'])."'");
  14. if (list($ID) = $DB->next_record()) {
  15. header("Location: user.php?id=$ID");
  16. error();
  17. }
  18. $_GET['username'] = $_GET['search'];
  19. } else {
  20. $_GET['comment'] = $_GET['search'];
  21. }
  22. }
  23. define('USERS_PER_PAGE', 30);
  24. function wrap($String, $ForceMatch = '', $IPSearch = false)
  25. {
  26. if (!$ForceMatch) {
  27. global $Match;
  28. } else {
  29. $Match = $ForceMatch;
  30. }
  31. if ($Match == ' REGEXP ') {
  32. if (strpos($String, '\'') !== false || preg_match('/^.*\\\\$/i', $String)) {
  33. error('Regex contains illegal characters.');
  34. }
  35. } else {
  36. $String = db_string($String);
  37. }
  38. if ($Match == ' LIKE ') {
  39. // Fuzzy search
  40. // Stick in wildcards at beginning and end of string unless string starts or ends with |
  41. if (($String[0] != '|') && !$IPSearch) {
  42. $String = "%$String";
  43. } elseif ($String[0] == '|') {
  44. $String = substr($String, 1, strlen($String));
  45. }
  46. if (substr($String, -1, 1) != '|') {
  47. $String = "$String%";
  48. } else {
  49. $String = substr($String, 0, -1);
  50. }
  51. }
  52. $String = "'$String'";
  53. return $String;
  54. }
  55. function date_compare($Field, $Operand, $Date1, $Date2 = '')
  56. {
  57. $Date1 = db_string($Date1);
  58. $Date2 = db_string($Date2);
  59. $Return = [];
  60. switch ($Operand) {
  61. case 'on':
  62. $Return [] = " $Field >= '$Date1 00:00:00' ";
  63. $Return [] = " $Field <= '$Date1 23:59:59' ";
  64. break;
  65. case 'before':
  66. $Return [] = " $Field < '$Date1 00:00:00' ";
  67. break;
  68. case 'after':
  69. $Return [] = " $Field > '$Date1 23:59:59' ";
  70. break;
  71. case 'between':
  72. $Return [] = " $Field >= '$Date1 00:00:00' ";
  73. $Return [] = " $Field <= '$Date2 00:00:00' ";
  74. break;
  75. }
  76. return $Return;
  77. }
  78. function num_compare($Field, $Operand, $Num1, $Num2 = '')
  79. {
  80. if ($Num1 != 0) {
  81. $Num1 = db_string($Num1);
  82. }
  83. if ($Num2 != 0) {
  84. $Num2 = db_string($Num2);
  85. }
  86. $Return = [];
  87. switch ($Operand) {
  88. case 'equal':
  89. $Return [] = " $Field = '$Num1' ";
  90. break;
  91. case 'above':
  92. $Return [] = " $Field > '$Num1' ";
  93. break;
  94. case 'below':
  95. $Return [] = " $Field < '$Num1' ";
  96. break;
  97. case 'between':
  98. $Return [] = " $Field > '$Num1' ";
  99. $Return [] = " $Field < '$Num2' ";
  100. break;
  101. default:
  102. print_r($Return);
  103. error();
  104. }
  105. return $Return;
  106. }
  107. // Arrays, regexes, and all that fun stuff we can use for validation, form generation, etc
  108. $DateChoices = array('inarray'=>array('on', 'before', 'after', 'between'));
  109. $SingleDateChoices = array('inarray'=>array('on', 'before', 'after'));
  110. $NumberChoices = array('inarray'=>array('equal', 'above', 'below', 'between', 'buffer'));
  111. $YesNo = array('inarray'=>array('any', 'yes', 'no'));
  112. $OrderVals = array('inarray'=>array('Username', 'Ratio', 'IP', 'Email', 'Joined', 'Last Seen', 'Uploaded', 'Downloaded', 'Invites', 'Snatches'));
  113. $WayVals = array('inarray'=>array('Ascending', 'Descending'));
  114. if (count($_GET)) {
  115. $DateRegex = array('regex' => '/\d{4}-\d{2}-\d{2}/');
  116. $ClassIDs = [];
  117. $SecClassIDs = [];
  118. foreach ($Classes as $ClassID => $Value) {
  119. if ($Value['Secondary']) {
  120. $SecClassIDs[] = $ClassID;
  121. } else {
  122. $ClassIDs[] = $ClassID;
  123. }
  124. }
  125. $Val->SetFields('comment', '0', 'string', 'Comment is too long.', array('maxlength' => 512));
  126. $Val->SetFields('disabled_invites', '0', 'inarray', 'Invalid disabled_invites field', $YesNo);
  127. $Val->SetFields('joined', '0', 'inarray', 'Invalid joined field', $DateChoices);
  128. $Val->SetFields('join1', '0', 'regex', 'Invalid join1 field', $DateRegex);
  129. $Val->SetFields('join2', '0', 'regex', 'Invalid join2 field', $DateRegex);
  130. $Val->SetFields('lastactive', '0', 'inarray', 'Invalid lastactive field', $DateChoices);
  131. $Val->SetFields('lastactive1', '0', 'regex', 'Invalid lastactive1 field', $DateRegex);
  132. $Val->SetFields('lastactive2', '0', 'regex', 'Invalid lastactive2 field', $DateRegex);
  133. $Val->SetFields('ratio', '0', 'inarray', 'Invalid ratio field', $NumberChoices);
  134. $Val->SetFields('uploaded', '0', 'inarray', 'Invalid uploaded field', $NumberChoices);
  135. $Val->SetFields('downloaded', '0', 'inarray', 'Invalid downloaded field', $NumberChoices);
  136. //$Val->SetFields('snatched', '0', 'inarray', 'Invalid snatched field', $NumberChoices);
  137. $Val->SetFields('matchtype', '0', 'inarray', 'Invalid matchtype field', array('inarray' => array('strict', 'fuzzy', 'regex')));
  138. $Val->SetFields('lockedaccount', '0', 'inarray', 'Invalid locked account field', array('inarray' => array('any', 'locked', 'unlocked')));
  139. $Val->SetFields('enabled', '0', 'inarray', 'Invalid enabled field', array('inarray' => array('', 0, 1, 2)));
  140. $Val->SetFields('class', '0', 'inarray', 'Invalid class', array('inarray' => $ClassIDs));
  141. $Val->SetFields('secclass', '0', 'inarray', 'Invalid class', array('inarray' => $SecClassIDs));
  142. $Val->SetFields('donor', '0', 'inarray', 'Invalid donor field', $YesNo);
  143. $Val->SetFields('warned', '0', 'inarray', 'Invalid warned field', $YesNo);
  144. $Val->SetFields('disabled_uploads', '0', 'inarray', 'Invalid disabled_uploads field', $YesNo);
  145. $Val->SetFields('order', '0', 'inarray', 'Invalid ordering', $OrderVals);
  146. $Val->SetFields('way', '0', 'inarray', 'Invalid way', $WayVals);
  147. $Val->SetFields('passkey', '0', 'string', 'Invalid passkey', array('maxlength' => 32));
  148. $Val->SetFields('avatar', '0', 'string', 'Avatar URL too long', array('maxlength' => 512));
  149. $Val->SetFields('stylesheet', '0', 'inarray', 'Invalid stylesheet', array_unique(array_keys($Stylesheets)));
  150. $Val->SetFields('cc', '0', 'inarray', 'Invalid Country Code', array('maxlength' => 2));
  151. $Err = $Val->ValidateForm($_GET);
  152. if (!$Err) {
  153. // Passed validation. Let's rock.
  154. $RunQuery = false; // if we should run the search
  155. if (isset($_GET['matchtype']) && $_GET['matchtype'] == 'strict') {
  156. $Match = ' = ';
  157. } elseif (isset($_GET['matchtype']) && $_GET['matchtype'] == 'regex') {
  158. $Match = ' REGEXP ';
  159. } else {
  160. $Match = ' LIKE ';
  161. }
  162. $OrderTable = array(
  163. 'Username' => 'um1.Username',
  164. 'Joined' => 'ui1.JoinDate',
  165. 'Email' => 'um1.Email',
  166. 'IP' => 'um1.IP',
  167. 'Last Seen' => 'um1.LastAccess',
  168. 'Uploaded' => 'um1.Uploaded',
  169. 'Downloaded' => 'um1.Downloaded',
  170. 'Ratio' => '(um1.Uploaded / um1.Downloaded)',
  171. 'Invites' => 'um1.Invites',
  172. 'Snatches' => 'Snatches');
  173. $WayTable = array('Ascending'=>'ASC', 'Descending'=>'DESC');
  174. $Where = [];
  175. $Having = [];
  176. $Join = [];
  177. $Group = [];
  178. $Distinct = '';
  179. $Order = '';
  180. $SQL = '
  181. SQL_CALC_FOUND_ROWS
  182. um1.ID,
  183. um1.Username,
  184. um1.Uploaded,
  185. um1.Downloaded,';
  186. if ($_GET['snatched'] == 'off') {
  187. $SQL .= "'X' AS Snatches,";
  188. } else {
  189. $SQL .= "
  190. (
  191. SELECT COUNT(xs.uid)
  192. FROM xbt_snatched AS xs
  193. WHERE xs.uid = um1.ID
  194. ) AS Snatches,";
  195. }
  196. if ($_GET['invitees'] == 'off') {
  197. $SQL .= "'X' AS Invitees,";
  198. } else {
  199. $SQL .= "
  200. (
  201. SELECT COUNT(ui2.UserID)
  202. FROM users_info AS ui2
  203. WHERE um1.ID = ui2.Inviter
  204. ) AS Invitees,";
  205. }
  206. $SQL .= '
  207. um1.PermissionID,
  208. um1.Email,
  209. um1.Enabled,
  210. um1.IP,
  211. um1.Invites,
  212. ui1.DisableInvites,
  213. ui1.Warned,
  214. ui1.Donor,
  215. ui1.JoinDate,
  216. um1.LastAccess
  217. FROM users_main AS um1
  218. JOIN users_info AS ui1 ON ui1.UserID = um1.ID ';
  219. if (!empty($_GET['username'])) {
  220. $Where[] = 'um1.Username'.$Match.wrap($_GET['username']);
  221. }
  222. if (!empty($_GET['email'])) {
  223. $Join['the'] = ' JOIN users_emails_decrypted AS he ON he.ID = um1.ID ';
  224. $Where[] = ' he.Email '.$Match.wrap($_GET['email']);
  225. }
  226. if (!empty($_GET['ip'])) {
  227. if (isset($_GET['ip_history'])) {
  228. $Distinct = 'DISTINCT ';
  229. }
  230. $Join['tip'] = ' JOIN users_ips_decrypted AS tip ON tip.ID = um1.ID ';
  231. $Where[] = ' tip.IP '.$Match.wrap($_GET['ip'], '', true);
  232. }
  233. if ($_GET['lockedaccount'] != '' && $_GET['lockedaccount'] != 'any') {
  234. $Join['la'] = '';
  235. if ($_GET['lockedaccount'] == 'unlocked') {
  236. $Join['la'] .= ' LEFT';
  237. $Where[] = ' la.UserID IS NULL';
  238. }
  239. $Join['la'] .= ' JOIN locked_accounts AS la ON la.UserID = um1.ID ';
  240. }
  241. if (!empty($_GET['tracker_ip'])) {
  242. $Distinct = 'DISTINCT ';
  243. $Join['xfu'] = ' JOIN xbt_files_users AS xfu ON um1.ID = xfu.uid ';
  244. $Where[] = ' xfu.ip '.$Match.wrap($_GET['tracker_ip'], '', true);
  245. }
  246. // if (!empty($_GET['tracker_ip'])) {
  247. // $Distinct = 'DISTINCT ';
  248. // $Join['xs'] = ' JOIN xbt_snatched AS xs ON um1.ID = xs.uid ';
  249. // $Where[] = ' xs.IP '.$Match.wrap($_GET['ip']);
  250. // }
  251. if (!empty($_GET['comment'])) {
  252. $Where[] = 'ui1.AdminComment'.$Match.wrap($_GET['comment']);
  253. }
  254. if (strlen($_GET['invites1'])) {
  255. $Invites1 = round($_GET['invites1']);
  256. $Invites2 = round($_GET['invites2']);
  257. $Where[] = implode(' AND ', num_compare('Invites', $_GET['invites'], $Invites1, $Invites2));
  258. }
  259. if (strlen($_GET['invitees1']) && $_GET['invitees'] != 'off') {
  260. $Invitees1 = round($_GET['invitees1']);
  261. $Invitees2 = round($_GET['invitees2']);
  262. $Having[] = implode(' AND ', num_compare('Invitees', $_GET['invitees'], $Invitees1, $Invitees2));
  263. }
  264. if ($_GET['disabled_invites'] == 'yes') {
  265. $Where[] = 'ui1.DisableInvites = \'1\'';
  266. } elseif ($_GET['disabled_invites'] == 'no') {
  267. $Where[] = 'ui1.DisableInvites = \'0\'';
  268. }
  269. if ($_GET['disabled_uploads'] == 'yes') {
  270. $Where[] = 'ui1.DisableUpload = \'1\'';
  271. } elseif ($_GET['disabled_uploads'] == 'no') {
  272. $Where[] = 'ui1.DisableUpload = \'0\'';
  273. }
  274. if ($_GET['join1']) {
  275. $Where[] = implode(' AND ', date_compare('ui1.JoinDate', $_GET['joined'], $_GET['join1'], $_GET['join2']));
  276. }
  277. if ($_GET['lastactive1']) {
  278. $Where[] = implode(' AND ', date_compare('um1.LastAccess', $_GET['lastactive'], $_GET['lastactive1'], $_GET['lastactive2']));
  279. }
  280. if ($_GET['ratio1']) {
  281. $Decimals = strlen(array_pop(explode('.', $_GET['ratio1'])));
  282. if (!$Decimals) {
  283. $Decimals = 0;
  284. }
  285. $Where[] = implode(' AND ', num_compare("ROUND(Uploaded/Downloaded,$Decimals)", $_GET['ratio'], $_GET['ratio1'], $_GET['ratio2']));
  286. }
  287. if (strlen($_GET['uploaded1'])) {
  288. $Upload1 = round($_GET['uploaded1']);
  289. $Upload2 = round($_GET['uploaded2']);
  290. if ($_GET['uploaded'] != 'buffer') {
  291. $Where[] = implode(' AND ', num_compare('ROUND(Uploaded / 1024 / 1024 / 1024)', $_GET['uploaded'], $Upload1, $Upload2));
  292. } else {
  293. $Where[] = implode(' AND ', num_compare('ROUND((Uploaded / 1024 / 1024 / 1024) - (Downloaded / 1024 / 1024 / 1023))', 'between', $Upload1 * 0.9, $Upload1 * 1.1));
  294. }
  295. }
  296. if (strlen($_GET['downloaded1'])) {
  297. $Download1 = round($_GET['downloaded1']);
  298. $Download2 = round($_GET['downloaded2']);
  299. $Where[] = implode(' AND ', num_compare('ROUND(Downloaded / 1024 / 1024 / 1024)', $_GET['downloaded'], $Download1, $Download2));
  300. }
  301. if (strlen($_GET['snatched1'])) {
  302. $Snatched1 = round($_GET['snatched1']);
  303. $Snatched2 = round($_GET['snatched2']);
  304. $Having[] = implode(' AND ', num_compare('Snatches', $_GET['snatched'], $Snatched1, $Snatched2));
  305. }
  306. if ($_GET['enabled'] != '') {
  307. $Where[] = 'um1.Enabled = '.wrap($_GET['enabled'], '=');
  308. }
  309. if ($_GET['class'] != '') {
  310. $Where[] = 'um1.PermissionID = '.wrap($_GET['class'], '=');
  311. }
  312. if ($_GET['secclass'] != '') {
  313. $Join['ul'] = ' JOIN users_levels AS ul ON um1.ID = ul.UserID ';
  314. $Where[] = 'ul.PermissionID = '.wrap($_GET['secclass'], '=');
  315. }
  316. if ($_GET['donor'] == 'yes') {
  317. $Where[] = 'ui1.Donor = \'1\'';
  318. } elseif ($_GET['donor'] == 'no') {
  319. $Where[] = 'ui1.Donor = \'0\'';
  320. }
  321. if ($_GET['warned'] == 'yes') {
  322. $Where[] = 'ui1.Warned IS NOT NULL';
  323. } elseif ($_GET['warned'] == 'no') {
  324. $Where[] = 'ui1.Warned IS NULL';
  325. }
  326. if ($_GET['disabled_ip']) {
  327. $Distinct = 'DISTINCT ';
  328. if ($_GET['ip_history']) {
  329. if (!isset($Join['tip'])) {
  330. $Join['tip'] = ' JOIN users_ips_decrypted AS tip ON tip.ID = um1.ID ';
  331. }
  332. $Join['tip2'] = ' JOIN users_ips_decrypted2 AS tip2 ON tip2.IP = tip.IP ';
  333. $Join['um2'] = ' JOIN users_main AS um2 ON um2.ID = tip2.ID AND um2.Enabled = \'2\' ';
  334. } else {
  335. $Join['um2'] = ' JOIN users_main AS um2 ON um2.IP = um1.IP AND um2.Enabled = \'2\' ';
  336. }
  337. }
  338. if (!empty($_GET['passkey'])) {
  339. $Where[] = 'um1.torrent_pass'.$Match.wrap($_GET['passkey']);
  340. }
  341. if (!empty($_GET['avatar'])) {
  342. $Where[] = 'ui1.Avatar'.$Match.wrap($_GET['avatar']);
  343. }
  344. if ($_GET['stylesheet'] != '') {
  345. $Where[] = 'ui1.StyleID = '.wrap($_GET['stylesheet'], '=');
  346. }
  347. if ($OrderTable[$_GET['order']] && $WayTable[$_GET['way']]) {
  348. $Order = ' ORDER BY '.$OrderTable[$_GET['order']].' '.$WayTable[$_GET['way']].' ';
  349. }
  350. //---------- Finish generating the search string
  351. $SQL = 'SELECT '.$Distinct.$SQL;
  352. $SQL .= implode(' ', $Join);
  353. if (count($Where)) {
  354. $SQL .= ' WHERE '.implode(' AND ', $Where);
  355. }
  356. if (count($Group)) {
  357. $SQL .= " GROUP BY " . implode(' ,', $Group);
  358. }
  359. if (count($Having)) {
  360. $SQL .= ' HAVING '.implode(' AND ', $Having);
  361. }
  362. $SQL .= $Order;
  363. if (count($Where) > 0 || count($Join) > 0 || count($Having) > 0) {
  364. $RunQuery = true;
  365. }
  366. list($Page, $Limit) = Format::page_limit(USERS_PER_PAGE);
  367. $SQL .= " LIMIT $Limit";
  368. } else {
  369. error($Err);
  370. }
  371. }
  372. View::show_header('User search');
  373. ?>
  374. <div>
  375. <form class="search_form" name="users" action="user.php" method="get">
  376. <input type="hidden" name="action" value="search" />
  377. <table class="layout">
  378. <tr>
  379. <td class="label nobr">Username:</td>
  380. <td width="24%">
  381. <input type="text" name="username" size="20"
  382. value="<?=display_str($_GET['username'])?>" />
  383. </td>
  384. <td class="label nobr">Joined:</td>
  385. <td width="24%">
  386. <select name="joined">
  387. <option value="on" <?php if ($_GET['joined'] === 'on') {
  388. echo ' selected="selected"';
  389. } ?>>On
  390. </option>
  391. <option value="before" <?php if ($_GET['joined'] === 'before') {
  392. echo ' selected="selected"';
  393. } ?>>Before
  394. </option>
  395. <option value="after" <?php if ($_GET['joined'] === 'after') {
  396. echo ' selected="selected"';
  397. } ?>>After
  398. </option>
  399. <option value="between" <?php if ($_GET['joined']==='between') {
  400. echo ' selected="selected"' ;
  401. } ?>>Between
  402. </option>
  403. </select>
  404. <input type="text" name="join1" size="10"
  405. value="<?=display_str($_GET['join1'])?>"
  406. placeholder="YYYY-MM-DD" />
  407. <input type="text" name="join2" size="10"
  408. value="<?=display_str($_GET['join2'])?>"
  409. placeholder="YYYY-MM-DD" />
  410. </td>
  411. <td class="label nobr">Enabled:</td>
  412. <td>
  413. <select name="enabled">
  414. <option value="" <?php if ($_GET['enabled'] === '') {
  415. echo ' selected="selected"';
  416. } ?>>Any
  417. </option>
  418. <option value="0" <?php if ($_GET['enabled']==='0') {
  419. echo ' selected="selected"' ;
  420. } ?>>Unconfirmed
  421. </option>
  422. <option value="1" <?php if ($_GET['enabled']==='1') {
  423. echo ' selected="selected"' ;
  424. } ?>>Enabled
  425. </option>
  426. <option value="2" <?php if ($_GET['enabled']==='2') {
  427. echo ' selected="selected"' ;
  428. } ?>>Disabled
  429. </option>
  430. </select>
  431. </td>
  432. </tr>
  433. <tr>
  434. <td class="label nobr">Email address:</td>
  435. <td>
  436. <input type="text" name="email" size="20"
  437. value="<?=display_str($_GET['email'])?>" />
  438. </td>
  439. <td class="label nobr">Last active:</td>
  440. <td width="30%">
  441. <select name="lastactive">
  442. <option value="on" <?php if ($_GET['lastactive'] === 'on') {
  443. echo ' selected="selected"';
  444. } ?>>On
  445. </option>
  446. <option value="before" <?php if ($_GET['lastactive'] === 'before') {
  447. echo ' selected="selected"';
  448. } ?>>Before
  449. </option>
  450. <option value="after" <?php if ($_GET['lastactive'] === 'after') {
  451. echo ' selected="selected"';
  452. } ?>>After
  453. </option>
  454. <option value="between" <?php if ($_GET['lastactive']==='between') {
  455. echo ' selected="selected"' ;
  456. } ?>
  457. >Between
  458. </option>
  459. </select>
  460. <input type="text" name="lastactive1" size="10"
  461. value="<?=display_str($_GET['lastactive1'])?>"
  462. placeholder="YYYY-MM-DD" />
  463. <input type="text" name="lastactive2" size="10"
  464. value="<?=display_str($_GET['lastactive2'])?>"
  465. placeholder="YYYY-MM-DD" />
  466. </td>
  467. <td class="label nobr">Primary class:</td>
  468. <td>
  469. <select name="class">
  470. <option value="" <?php if ($_GET['class']==='') {
  471. echo ' selected="selected"' ;
  472. } ?>>Any
  473. </option>
  474. <?php foreach ($ClassLevels as $Class) {
  475. if ($Class['Secondary']) {
  476. continue;
  477. } ?>
  478. <option value="<?=$Class['ID'] ?>"
  479. <?php
  480. if ($_GET['class']===$Class['ID']) {
  481. echo ' selected="selected"' ;
  482. } ?>><?=Format::cut_string($Class['Name'], 10, 1, 1).' ('.$Class['Level'].')'?>
  483. </option>
  484. <?php
  485. } ?>
  486. </select>
  487. </td>
  488. </tr>
  489. <tr>
  490. <td class="label tooltip nobr"
  491. title="To fuzzy search (default) for a block of addresses (e.g. 55.66.77.*), enter &quot;55.66.77.&quot; without the quotes">
  492. IP address:</td>
  493. <td>
  494. <input type="text" name="ip" size="20"
  495. value="<?=display_str($_GET['ip'])?>" />
  496. </td>
  497. <td class="label nobr">Locked Account:</td>
  498. <td>
  499. <select name="lockedaccount">
  500. <option value="any" <?php if ($_GET['lockedaccount']=='any') {
  501. echo ' selected="selected"' ;
  502. } ?>>Any
  503. </option>
  504. <option value="locked" <?php if ($_GET['lockedaccount']=='locked') {
  505. echo ' selected="selected"' ;
  506. } ?>>Locked
  507. </option>
  508. <option value="unlocked" <?php if ($_GET['lockedaccount']=='unlocked') {
  509. echo ' selected="selected"' ;
  510. } ?>
  511. >Unlocked
  512. </option>
  513. </select>
  514. </td>
  515. <td class="label nobr">Secondary class:</td>
  516. <td>
  517. <select name="secclass">
  518. <option value="" <?php if ($_GET['secclass']==='') {
  519. echo ' selected="selected"' ;
  520. } ?>>Any
  521. </option>
  522. <?php $Secondaries = [];
  523. // Neither level nor ID is particularly useful when searching secondary classes, so let's do some
  524. // kung-fu to sort them alphabetically.
  525. $fnc = function ($Class1, $Class2) {
  526. return strcmp($Class1['Name'], $Class2['Name']);
  527. };
  528. foreach ($ClassLevels as $Class) {
  529. if (!$Class['Secondary']) {
  530. continue;
  531. }
  532. $Secondaries[] = $Class;
  533. }
  534. usort($Secondaries, $fnc);
  535. foreach ($Secondaries as $Class) {
  536. ?>
  537. <option value="<?=$Class['ID'] ?>"
  538. <?php
  539. if ($_GET['secclass']===$Class['ID']) {
  540. echo ' selected="selected"' ;
  541. } ?>><?=Format::cut_string($Class['Name'], 20, 1, 1)?>
  542. </option>
  543. <?php
  544. } ?>
  545. </select>
  546. </td>
  547. </tr>
  548. <tr>
  549. <td class="label nobr">Extra:</td>
  550. <td>
  551. <ul class="options_list nobullet">
  552. <li>
  553. <input type="checkbox" name="ip_history" id="ip_history" <?php if ($_GET['ip_history']) {
  554. echo ' checked="checked"' ;
  555. } ?> />
  556. <label for="ip_history">IP history</label>
  557. </li>
  558. </ul>
  559. </td>
  560. <td class="label nobr">Ratio:</td>
  561. <td width="30%">
  562. <select name="ratio">
  563. <option value="equal" <?php if ($_GET['ratio'] === 'equal') {
  564. echo ' selected="selected"';
  565. } ?>>Equal
  566. </option>
  567. <option value="above" <?php if ($_GET['ratio'] === 'above') {
  568. echo ' selected="selected"';
  569. } ?>>Above
  570. </option>
  571. <option value="below" <?php if ($_GET['ratio'] === 'below') {
  572. echo ' selected="selected"';
  573. } ?>>Below
  574. </option>
  575. <option value="between" <?php if ($_GET['ratio']==='between') {
  576. echo ' selected="selected"' ;
  577. } ?>>Between
  578. </option>
  579. </select>
  580. <input type="text" name="ratio1" size="6"
  581. value="<?=display_str($_GET['ratio1'])?>" />
  582. <input type="text" name="ratio2" size="6"
  583. value="<?=display_str($_GET['ratio2'])?>" />
  584. </td>
  585. <td class="label nobr">Donor:</td>
  586. <td>
  587. <select name="donor">
  588. <option value="" <?php if ($_GET['donor'] === '') {
  589. echo ' selected="selected"';
  590. } ?>>Any
  591. </option>
  592. <option value="yes" <?php if ($_GET['donor']==='yes') {
  593. echo ' selected="selected"' ;
  594. } ?>>Yes
  595. </option>
  596. <option value="no" <?php if ($_GET['donor'] === 'no') {
  597. echo ' selected="selected"';
  598. } ?>>No
  599. </option>
  600. </select>
  601. </td>
  602. </tr>
  603. <tr>
  604. <?php if (check_perms('users_mod')) { ?>
  605. <td class="label nobr">Staff notes:</td>
  606. <td>
  607. <input type="text" name="comment" size="20"
  608. value="<?=display_str($_GET['comment'])?>" />
  609. </td>
  610. <?php } else { ?>
  611. <td class="label nobr"></td>
  612. <td>
  613. </td>
  614. <?php } ?>
  615. <td class="label tooltip nobr" title="Units are in gibibytes (the base 2 sibling of gigabytes)">Uploaded:</td>
  616. <td width="30%">
  617. <select name="uploaded">
  618. <option value="equal" <?php if ($_GET['uploaded'] === 'equal') {
  619. echo ' selected="selected"';
  620. } ?>>Equal
  621. </option>
  622. <option value="above" <?php if ($_GET['uploaded'] === 'above') {
  623. echo ' selected="selected"';
  624. } ?>>Above
  625. </option>
  626. <option value="below" <?php if ($_GET['uploaded'] === 'below') {
  627. echo ' selected="selected"';
  628. } ?>>Below
  629. </option>
  630. <option value="between" <?php if ($_GET['uploaded']==='between') {
  631. echo ' selected="selected"' ;
  632. } ?>>Between
  633. </option>
  634. <option value="buffer" <?php if ($_GET['uploaded'] === 'buffer') {
  635. echo ' selected="selected"';
  636. } ?>>Buffer
  637. </option>
  638. </select>
  639. <input type="text" name="uploaded1" size="6"
  640. value="<?=display_str($_GET['uploaded1'])?>" />
  641. <input type="text" name="uploaded2" size="6"
  642. value="<?=display_str($_GET['uploaded2'])?>" />
  643. </td>
  644. <td class="label nobr">Warned:</td>
  645. <td>
  646. <select name="warned">
  647. <option value="" <?php if ($_GET['warned'] === '') {
  648. echo ' selected="selected"';
  649. } ?>>Any
  650. </option>
  651. <option value="yes" <?php if ($_GET['warned']==='yes') {
  652. echo ' selected="selected"' ;
  653. } ?>>Yes
  654. </option>
  655. <option value="no" <?php if ($_GET['warned'] === 'no') {
  656. echo ' selected="selected"';
  657. } ?>>No
  658. </option>
  659. </select>
  660. </td>
  661. </tr>
  662. <tr>
  663. <td class="label nobr"># of invites:</td>
  664. <td>
  665. <select name="invites">
  666. <option value="equal" <?php if ($_GET['invites'] === 'equal') {
  667. echo ' selected="selected"';
  668. } ?>>Equal
  669. </option>
  670. <option value="above" <?php if ($_GET['invites'] === 'above') {
  671. echo ' selected="selected"';
  672. } ?>>Above
  673. </option>
  674. <option value="below" <?php if ($_GET['invites'] === 'below') {
  675. echo ' selected="selected"';
  676. } ?>>Below
  677. </option>
  678. <option value="between" <?php if ($_GET['invites']==='between') {
  679. echo ' selected="selected"' ;
  680. } ?>>Between
  681. </option>
  682. </select>
  683. <input type="text" name="invites1" size="6"
  684. value="<?=display_str($_GET['invites1'])?>" />
  685. <input type="text" name="invites2" size="6"
  686. value="<?=display_str($_GET['invites2'])?>" />
  687. </td>
  688. <td class="label tooltip nobr" title="Units are in gibibytes (the base 2 sibling of gigabytes)">Downloaded:</td>
  689. <td width="30%">
  690. <select name="downloaded">
  691. <option value="equal" <?php if ($_GET['downloaded'] === 'equal') {
  692. echo ' selected="selected"';
  693. } ?>>Equal
  694. </option>
  695. <option value="above" <?php if ($_GET['downloaded'] === 'above') {
  696. echo ' selected="selected"';
  697. } ?>>Above
  698. </option>
  699. <option value="below" <?php if ($_GET['downloaded'] === 'below') {
  700. echo ' selected="selected"';
  701. } ?>>Below
  702. </option>
  703. <option value="between" <?php if ($_GET['downloaded']==='between') {
  704. echo ' selected="selected"' ;
  705. } ?>
  706. >Between
  707. </option>
  708. </select>
  709. <input type="text" name="downloaded1" size="6"
  710. value="<?=display_str($_GET['downloaded1'])?>" />
  711. <input type="text" name="downloaded2" size="6"
  712. value="<?=display_str($_GET['downloaded2'])?>" />
  713. </td>
  714. <td class="label tooltip nobr" title="Only display users that have a disabled account linked by IP address">
  715. <label for="disabled_ip">Disabled accounts<br />linked by IP:</label>
  716. </td>
  717. <td>
  718. <input type="checkbox" name="disabled_ip" id="disabled_ip" <?php if ($_GET['disabled_ip']) {
  719. echo ' checked="checked"' ;
  720. } ?> />
  721. </td>
  722. </tr>
  723. <tr>
  724. <td class="label nobr">Disabled invites:</td>
  725. <td>
  726. <select name="disabled_invites">
  727. <option value="" <?php if ($_GET['disabled_invites'] === '') {
  728. echo ' selected="selected"';
  729. } ?>>Any
  730. </option>
  731. <option value="yes" <?php if ($_GET['disabled_invites']==='yes') {
  732. echo ' selected="selected"' ;
  733. } ?>>Yes
  734. </option>
  735. <option value="no" <?php if ($_GET['disabled_invites'] === 'no') {
  736. echo ' selected="selected"';
  737. } ?>>No
  738. </option>
  739. </select>
  740. </td>
  741. <td class="label nobr">Snatched:</td>
  742. <td width="30%">
  743. <select name="snatched">
  744. <option value="equal" <?php if (isset($_GET['snatched']) && $_GET['snatched'] === 'equal') {
  745. echo ' selected="selected"';
  746. } ?>>Equal
  747. </option>
  748. <option value="above" <?php if (isset($_GET['snatched']) && $_GET['snatched'] === 'above') {
  749. echo ' selected="selected"';
  750. } ?>>Above
  751. </option>
  752. <option value="below" <?php if (isset($_GET['snatched']) && $_GET['snatched'] === 'below') {
  753. echo ' selected="selected"';
  754. } ?>>Below
  755. </option>
  756. <option value="between" <?php if (isset($_GET['snatched']) && $_GET['snatched']==='between') {
  757. echo ' selected="selected"' ;
  758. } ?>>Between
  759. </option>
  760. <option value="off" <?php if (!isset($_GET['snatched']) || $_GET['snatched'] === 'off') {
  761. echo ' selected="selected"';
  762. } ?>>Off
  763. </option>
  764. </select>
  765. <input type="text" name="snatched1" size="6"
  766. value="<?=display_str($_GET['snatched1'])?>" />
  767. <input type="text" name="snatched2" size="6"
  768. value="<?=display_str($_GET['snatched2'])?>" />
  769. </td>
  770. <td class="label nobr">Disabled uploads:</td>
  771. <td>
  772. <select name="disabled_uploads">
  773. <option value="" <?php if (isset($_GET['disabled_uploads']) && $_GET['disabled_uploads'] === '') {
  774. echo ' selected="selected"';
  775. } ?>>Any
  776. </option>
  777. <option value="yes" <?php if (isset($_GET['disabled_uploads']) && $_GET['disabled_uploads']==='yes') {
  778. echo ' selected="selected"' ;
  779. } ?>>Yes
  780. </option>
  781. <option value="no" <?php if (isset($_GET['disabled_uploads']) && $_GET['disabled_uploads'] === 'no') {
  782. echo ' selected="selected"';
  783. } ?>>No
  784. </option>
  785. </select>
  786. </td>
  787. </tr>
  788. <tr>
  789. <td width="30%" class="label nobr"># of invitees:</td>
  790. <td>
  791. <select name="invitees">
  792. <option value="equal" <?=isset($_GET['invitees']) && $_GET['invitees'] == 'equal' ? 'selected' : ''?>>Equal
  793. </option>
  794. <option value="above" <?=isset($_GET['invitees']) && $_GET['invitees'] == 'above' ? 'selected' : ''?>>Above
  795. </option>
  796. <option value="below" <?=isset($_GET['invitees']) && $_GET['invitees'] == 'below' ? 'selected' : ''?>>Below
  797. </option>
  798. <option value="between" <?=isset($_GET['invitees']) && $_GET['invitees'] == 'between' ? 'selected' : ''?>>Between
  799. </option>
  800. <option value="off" <?=!isset($_GET['invitees']) || $_GET['invitees'] == 'off' ? 'selected' : ''?>>Off
  801. </option>
  802. </select>
  803. <input type="text" name="invitees1" size="6"
  804. value="<?=display_str($_GET['invitees1'])?>" />
  805. <input type="text" name="invitees2" size="6"
  806. value="<?=display_str($_GET['invitees2'])?>" />
  807. </td>
  808. <td class="label nobr">Passkey:</td>
  809. <td>
  810. <input type="text" name="passkey" size="20"
  811. value="<?=display_str($_GET['passkey'])?>" />
  812. </td>
  813. <td class="label nobr">Tracker IP:</td>
  814. <td>
  815. <input type="text" name="tracker_ip" size="20"
  816. value="<?=display_str($_GET['tracker_ip'])?>" />
  817. </td>
  818. </tr>
  819. <tr>
  820. <td class="label tooltip nobr"
  821. title="Supports partial URL matching, e.g. entering &quot;&#124;https://whatimg.com&quot; will search for avatars hosted on https://whatimg.com">
  822. Avatar URL:</td>
  823. <td>
  824. <input type="text" name="avatar" size="20"
  825. value="<?=display_str($_GET['avatar'])?>" />
  826. </td>
  827. <td class="label nobr">Stylesheet:</td>
  828. <td>
  829. <select name="stylesheet" id="stylesheet">
  830. <option value="">Any</option>
  831. <?php foreach ($Stylesheets as $Style) { ?>
  832. <option value="<?=$Style['ID']?>"
  833. <?Format::selected('stylesheet', $Style['ID'])?>><?=$Style['ProperName']?>
  834. </option>
  835. <?php } ?>
  836. </select>
  837. </td>
  838. <td class="label tooltip nobr" title="Two-letter codes as defined in ISO 3166-1 alpha-2">Country code:</td>
  839. <td width="30%">
  840. <select name="cc_op">
  841. <option value="equal" <?php if ($_GET['cc_op'] === 'equal') {
  842. echo ' selected="selected"';
  843. } ?>>Equals
  844. </option>
  845. <option value="not_equal" <?php if ($_GET['cc_op']==='not_equal') {
  846. echo ' selected="selected"' ;
  847. } ?>>Not
  848. equal
  849. </option>
  850. </select>
  851. <input type="text" name="cc" size="2"
  852. value="<?=display_str($_GET['cc'])?>" />
  853. </td>
  854. </tr>
  855. <tr>
  856. <td class="label nobr">Search type:</td>
  857. <td>
  858. <ul class="options_list nobullet">
  859. <li>
  860. <input type="radio" name="matchtype" id="strict_match_type" value="strict" <?php if ($_GET['matchtype']=='strict' || !$_GET['matchtype']) {
  861. echo ' checked="checked"' ;
  862. } ?> />
  863. <label class="tooltip"
  864. title="A &quot;strict&quot; search uses no wildcards in search fields, and it is analogous to &#96;grep -E &quot;&circ;SEARCHTERM&#36;&quot;&#96;"
  865. for="strict_match_type">Strict</label>
  866. </li>
  867. <li>
  868. <input type="radio" name="matchtype" id="fuzzy_match_type" value="fuzzy" <?php if ($_GET['matchtype']=='fuzzy' || !$_GET['matchtype']) {
  869. echo ' checked="checked"' ;
  870. } ?> />
  871. <label class="tooltip"
  872. title="A &quot;fuzzy&quot; search automatically prepends and appends wildcards to search strings, except for IP address searches, unless the search string begins or ends with a &quot;&#124;&quot; (pipe). It is analogous to a vanilla grep search (except for the pipe stuff)."
  873. for="fuzzy_match_type">Fuzzy</label>
  874. </li>
  875. <li>
  876. <input type="radio" name="matchtype" id="regex_match_type" value="regex" <?php if ($_GET['matchtype']=='regex') {
  877. echo ' checked="checked"' ;
  878. } ?> />
  879. <label class="tooltip" title="A &quot;regex&quot; search uses MySQL's regular expression syntax."
  880. for="regex_match_type">Regex</label>
  881. </li>
  882. </ul>
  883. </td>
  884. <td class="label nobr">Order:</td>
  885. <td class="nobr">
  886. <select name="order">
  887. <?php
  888. foreach (array_shift($OrderVals) as $Cur) { ?>
  889. <option value="<?=$Cur?>" <?php if (isset($_GET['order']) &&
  890. $_GET['order']==$Cur || (!isset($_GET['order']) && $Cur=='Joined')) {
  891. echo ' selected="selected"' ;
  892. } ?>
  893. ><?=$Cur?>
  894. </option>
  895. <?php } ?>
  896. </select>
  897. <select name="way">
  898. <?php foreach (array_shift($WayVals) as $Cur) { ?>
  899. <option value="<?=$Cur?>" <?php if (isset($_GET['way']) &&
  900. $_GET['way']==$Cur || (!isset($_GET['way']) && $Cur=='Descending')) {
  901. echo ' selected="selected"' ;
  902. } ?>
  903. ><?=$Cur?>
  904. </option>
  905. <?php } ?>
  906. </select>
  907. </td>
  908. <td class="label nobr"># of emails:</td>
  909. <td>
  910. <select name="emails_opt">
  911. <option value="equal" <?php if ($_GET['emails_opt']==='equal') {
  912. echo ' selected="selected"' ;
  913. } ?>>Equal
  914. </option>
  915. <option value="above" <?php if ($_GET['emails_opt']==='above') {
  916. echo ' selected="selected"' ;
  917. } ?>>Above
  918. </option>
  919. <option value="below" <?php if ($_GET['emails_opt']==='below') {
  920. echo ' selected="selected"' ;
  921. } ?>>Below
  922. </option>
  923. </select>
  924. <input type="text" name="email_cnt" size="6"
  925. value="<?=display_str($_GET['email_cnt'])?>" />
  926. </td>
  927. </tr>
  928. <tr>
  929. <td colspan="6" class="center">
  930. <input type="submit" value="Search users" />
  931. </td>
  932. </tr>
  933. </table>
  934. </form>
  935. </div>
  936. <?php
  937. if ($RunQuery) {
  938. if (!empty($_GET['ip'])) {
  939. if (isset($_GET['ip_history'])) {
  940. $DB->query("SELECT UserID, IP FROM users_history_ips");
  941. } else {
  942. $DB->query("SELECT ID, IP FROM users_main");
  943. }
  944. while (list($ID, $EncIP) = $DB->next_record()) {
  945. $IPs[] = $ID.", '".Crypto::decrypt($EncIP)."'";
  946. }
  947. $DB->query("CREATE TEMPORARY TABLE users_ips_decrypted (ID INT(10) UNSIGNED NOT NULL, IP VARCHAR(45) NOT NULL, PRIMARY KEY (ID,IP)) ENGINE=MEMORY");
  948. $DB->query("INSERT IGNORE INTO users_ips_decrypted (ID, IP) VALUES(".implode("),(", $IPs).")");
  949. if ($_GET['disabled_ip'] && $_GET['ip_history']) {
  950. $DB->query("CREATE TEMPORARY TABLE users_ips_decrypted2 SELECT * FROM users_ips_decrypted");
  951. }
  952. }
  953. if (!empty($_GET['email'])) {
  954. $DB->query("SELECT ID, Email FROM users_main");
  955. while (list($ID, $EncEmail) = $DB->next_record()) {
  956. $Emails[] = $ID.", '".Crypto::decrypt($EncEmail)."'";
  957. }
  958. $DB->query("CREATE TEMPORARY TABLE users_emails_decrypted (ID INT(10) UNSIGNED NOT NULL, Email VARCHAR(255) NOT NULL, PRIMARY KEY (ID,Email)) ENGINE=MEMORY");
  959. $DB->query("INSERT IGNORE INTO users_emails_decrypted (ID, Email) VALUES(".implode("),(", $Emails).")");
  960. }
  961. $Results = $DB->query($SQL);
  962. $DB->query('SELECT FOUND_ROWS()');
  963. list($NumResults) = $DB->next_record();
  964. if (!empty($_GET['ip'])) {
  965. $DB->query("DROP TABLE users_ips_decrypted");
  966. }
  967. if (!empty($_GET['email'])) {
  968. $DB->query("DROP TABLE users_emails_decrypted");
  969. }
  970. $DB->set_query_id($Results);
  971. } else {
  972. $DB->query('SET @nothing = 0');
  973. $NumResults = 0;
  974. }
  975. ?>
  976. <div class="linkbox">
  977. <?php
  978. $Pages = Format::get_pages($Page, $NumResults, USERS_PER_PAGE, 11);
  979. echo $Pages;
  980. ?>
  981. </div>
  982. <div class="box pad center">
  983. <h2><?=number_format($NumResults)?> results</h2>
  984. <table width="100%">
  985. <tr class="colhead">
  986. <td>Username</td>
  987. <td>Ratio</td>
  988. <td>IP address</td>
  989. <td>Email</td>
  990. <td>Joined</td>
  991. <td>Last seen</td>
  992. <td>Upload</td>
  993. <td>Download</td>
  994. <td>Downloads</td>
  995. <td>Snatched</td>
  996. <td>Invites</td>
  997. <?php if (isset($_GET['invitees']) && $_GET['invitees'] != 'off') { ?>
  998. <td>Invitees</td>
  999. <?php } ?>
  1000. </tr>
  1001. <?php
  1002. while (list($UserID, $Username, $Uploaded, $Downloaded, $Snatched, $Invitees, $Class, $Email, $Enabled, $IP, $Invites, $DisableInvites, $Warned, $Donor, $JoinDate, $LastAccess) = $DB->next_record()) {
  1003. $IP = apcu_exists('DBKEY') ? Crypto::decrypt($IP) : '[Encrypted]';
  1004. $Email = apcu_exists('DBKEY') ? Crypto::decrypt($Email) : '[Encrypted]'; ?>
  1005. <tr>
  1006. <td><?=Users::format_username($UserID, true, true, true, true)?>
  1007. </td>
  1008. <td><?=Format::get_ratio_html($Uploaded, $Downloaded)?>
  1009. </td>
  1010. <td style="word-break: break-all;"><?=display_str($IP)?>
  1011. </td>
  1012. <td><?=display_str($Email)?>
  1013. </td>
  1014. <td><?=time_diff($JoinDate)?>
  1015. </td>
  1016. <td><?=time_diff($LastAccess)?>
  1017. </td>
  1018. <td><?=Format::get_size($Uploaded)?>
  1019. </td>
  1020. <td><?=Format::get_size($Downloaded)?>
  1021. </td>
  1022. <?php $DB->query("
  1023. SELECT COUNT(ud.UserID)
  1024. FROM users_downloads AS ud
  1025. JOIN torrents AS t ON t.ID = ud.TorrentID
  1026. WHERE ud.UserID = $UserID");
  1027. list($Downloads) = $DB->next_record();
  1028. $DB->set_query_id($Results); ?>
  1029. <td><?=number_format((int)$Downloads)?>
  1030. </td>
  1031. <td><?=(is_numeric($Snatched) ? number_format($Snatched) : display_str($Snatched))?>
  1032. </td>
  1033. <td>
  1034. <?php if ($DisableInvites) {
  1035. echo 'X';
  1036. } else {
  1037. echo number_format($Invites);
  1038. } ?>
  1039. </td>
  1040. <?php if (isset($_GET['invitees']) && $_GET['invitees'] != 'off') { ?>
  1041. <td><?=number_format($Invitees)?>
  1042. </td>
  1043. <?php } ?>
  1044. </tr>
  1045. <?php
  1046. }
  1047. ?>
  1048. </table>
  1049. </div>
  1050. <div class="linkbox">
  1051. <?=$Pages?>
  1052. </div>
  1053. <?php View::show_footer();