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.

user.php 53KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520
  1. <?
  2. if (empty($_GET['id']) || !is_number($_GET['id']) || (!empty($_GET['preview']) && !is_number($_GET['preview']))) {
  3. error(404);
  4. }
  5. $UserID = (int)$_GET['id'];
  6. $Preview = isset($_GET['preview']) ? $_GET['preview'] : 0;
  7. if ($UserID == $LoggedUser['ID']) {
  8. $OwnProfile = true;
  9. if ($Preview == 1) {
  10. $OwnProfile = false;
  11. $ParanoiaString = $_GET['paranoia'];
  12. $CustomParanoia = explode(',', $ParanoiaString);
  13. }
  14. } else {
  15. $OwnProfile = false;
  16. //Don't allow any kind of previewing on others' profiles
  17. $Preview = 0;
  18. }
  19. $EnabledRewards = Donations::get_enabled_rewards($UserID);
  20. $ProfileRewards = Donations::get_profile_rewards($UserID);
  21. if (check_perms('users_mod')) { // Person viewing is a staff member
  22. $DB->query("
  23. SELECT
  24. m.Username,
  25. m.Email,
  26. m.LastAccess,
  27. m.IP,
  28. p.Level AS Class,
  29. m.Uploaded,
  30. m.Downloaded,
  31. m.RequiredRatio,
  32. m.Title,
  33. m.torrent_pass,
  34. m.Enabled,
  35. m.Paranoia,
  36. m.Invites,
  37. m.can_leech,
  38. m.Visible,
  39. m.BonusPoints,
  40. m.IRCLines,
  41. i.JoinDate,
  42. i.Info,
  43. i.Avatar,
  44. i.AdminComment,
  45. i.Donor,
  46. i.Artist,
  47. i.Warned,
  48. i.SupportFor,
  49. i.RestrictedForums,
  50. i.PermittedForums,
  51. i.Inviter,
  52. inviter.Username,
  53. COUNT(posts.id) AS ForumPosts,
  54. i.RatioWatchEnds,
  55. i.RatioWatchDownload,
  56. i.DisableAvatar,
  57. i.DisableInvites,
  58. i.DisablePosting,
  59. i.DisableForums,
  60. i.DisableTagging,
  61. i.DisableUpload,
  62. i.DisableWiki,
  63. i.DisablePM,
  64. i.DisablePoints,
  65. i.DisablePromotion,
  66. i.DisableIRC,
  67. i.DisableRequests," . "
  68. m.FLTokens,
  69. SHA1(i.AdminComment),
  70. i.InfoTitle,
  71. la.Type AS LockedAccount
  72. FROM users_main AS m
  73. JOIN users_info AS i ON i.UserID = m.ID
  74. LEFT JOIN users_main AS inviter ON i.Inviter = inviter.ID
  75. LEFT JOIN permissions AS p ON p.ID = m.PermissionID
  76. LEFT JOIN forums_posts AS posts ON posts.AuthorID = m.ID
  77. LEFT JOIN locked_accounts AS la ON la.UserID = m.ID
  78. WHERE m.ID = '$UserID'
  79. GROUP BY AuthorID");
  80. if (!$DB->has_results()) { // If user doesn't exist
  81. header("Location: log.php?search=User+$UserID");
  82. }
  83. list($Username, $Email, $LastAccess, $IP, $Class, $Uploaded, $Downloaded, $RequiredRatio, $CustomTitle, $torrent_pass, $Enabled, $Paranoia, $Invites, $DisableLeech, $Visible, $BonusPoints, $IRCLines, $JoinDate, $Info, $Avatar, $AdminComment, $Donor, $Artist, $Warned, $SupportFor, $RestrictedForums, $PermittedForums, $InviterID, $InviterName, $ForumPosts, $RatioWatchEnds, $RatioWatchDownload, $DisableAvatar, $DisableInvites, $DisablePosting, $DisableForums, $DisableTagging, $DisableUpload, $DisableWiki, $DisablePM, $DisablePoints, $DisablePromotion, $DisableIRC, $DisableRequests, $FLTokens, $CommentHash, $InfoTitle, $LockedAccount) = $DB->next_record(MYSQLI_NUM, array(8, 11));
  84. } else { // Person viewing is a normal user
  85. $DB->query("
  86. SELECT
  87. m.Username,
  88. m.Email,
  89. m.LastAccess,
  90. m.IP,
  91. p.Level AS Class,
  92. m.Uploaded,
  93. m.Downloaded,
  94. m.RequiredRatio,
  95. m.Enabled,
  96. m.Paranoia,
  97. m.Invites,
  98. m.Title,
  99. m.torrent_pass,
  100. m.can_leech,
  101. i.JoinDate,
  102. i.Info,
  103. i.Avatar,
  104. m.FLTokens,
  105. m.BonusPoints,
  106. m.IRCLines,
  107. i.Donor,
  108. i.Warned,
  109. COUNT(posts.id) AS ForumPosts,
  110. i.Inviter,
  111. i.DisableInvites,
  112. inviter.username,
  113. i.InfoTitle
  114. FROM users_main AS m
  115. JOIN users_info AS i ON i.UserID = m.ID
  116. LEFT JOIN permissions AS p ON p.ID = m.PermissionID
  117. LEFT JOIN users_main AS inviter ON i.Inviter = inviter.ID
  118. LEFT JOIN forums_posts AS posts ON posts.AuthorID = m.ID
  119. WHERE m.ID = $UserID
  120. GROUP BY AuthorID");
  121. if (!$DB->has_results()) { // If user doesn't exist
  122. header("Location: log.php?search=User+$UserID");
  123. }
  124. list($Username, $Email, $LastAccess, $IP, $Class, $Uploaded, $Downloaded,
  125. $RequiredRatio, $Enabled, $Paranoia, $Invites, $CustomTitle, $torrent_pass,
  126. $DisableLeech, $JoinDate, $Info, $Avatar, $FLTokens, $BonusPoints, $IRCLines, $Donor, $Warned,
  127. $ForumPosts, $InviterID, $DisableInvites, $InviterName, $InfoTitle) = $DB->next_record(MYSQLI_NUM, array(9, 11));
  128. }
  129. $Email = apc_exists('DBKEY') ? DBCrypt::decrypt($Email) : '[Encrypted]';
  130. // Image proxy CTs
  131. $DisplayCustomTitle = $CustomTitle;
  132. if (check_perms('site_proxy_images') && !empty($CustomTitle)) {
  133. $DisplayCustomTitle = preg_replace_callback('~src=("?)(http.+?)(["\s>])~',
  134. function($Matches) {
  135. return 'src=' . $Matches[1] . ImageTools::process($Matches[2]) . $Matches[3];
  136. }, $CustomTitle);
  137. }
  138. if ($Preview == 1) {
  139. if (strlen($ParanoiaString) == 0) {
  140. $Paranoia = array();
  141. } else {
  142. $Paranoia = $CustomParanoia;
  143. }
  144. } else {
  145. $Paranoia = unserialize($Paranoia);
  146. if (!is_array($Paranoia)) {
  147. $Paranoia = array();
  148. }
  149. }
  150. $ParanoiaLevel = 0;
  151. foreach ($Paranoia as $P) {
  152. $ParanoiaLevel++;
  153. if (strpos($P, '+') !== false) {
  154. $ParanoiaLevel++;
  155. }
  156. }
  157. $JoinedDate = time_diff($JoinDate);
  158. $LastAccess = time_diff($LastAccess);
  159. function check_paranoia_here($Setting) {
  160. global $Paranoia, $Class, $UserID, $Preview;
  161. if ($Preview == 1) {
  162. return check_paranoia($Setting, $Paranoia, $Class);
  163. } else {
  164. return check_paranoia($Setting, $Paranoia, $Class, $UserID);
  165. }
  166. }
  167. View::show_header($Username, "jquery.imagesloaded,user,bbcode,requests,comments,info_paster,wall");
  168. ?>
  169. <div class="thin">
  170. <div class="header">
  171. <h2><?=Users::format_username($UserID, true, true, true, false, true)?></h2>
  172. </div>
  173. <div class="linkbox">
  174. <?
  175. if (!$OwnProfile) {
  176. ?>
  177. <a href="inbox.php?action=compose&amp;to=<?=$UserID?>" class="brackets">Send message</a>
  178. <?
  179. $DB->query("
  180. SELECT FriendID
  181. FROM friends
  182. WHERE UserID = '$LoggedUser[ID]'
  183. AND FriendID = '$UserID'");
  184. if (!$DB->has_results()) {
  185. ?>
  186. <a href="friends.php?action=add&amp;friendid=<?=$UserID?>&amp;auth=<?=$LoggedUser['AuthKey']?>" class="brackets">Add to friends</a>
  187. <? } ?>
  188. <a href="reports.php?action=report&amp;type=user&amp;id=<?=$UserID?>" class="brackets">Report user</a>
  189. <?
  190. }
  191. if (check_perms('users_edit_profiles', $Class) || $LoggedUser['ID'] == $UserID) {
  192. ?>
  193. <a href="user.php?action=edit&amp;userid=<?=$UserID?>" class="brackets">Settings</a>
  194. <?
  195. }
  196. if ($LoggedUser['ID'] == $UserID) {
  197. ?>
  198. <a href="userhistory.php?action=useremail&userid=<?=$UserID?>" class="brackets">Email History</a>
  199. <?
  200. }
  201. if (check_perms('users_view_invites', $Class)) {
  202. ?>
  203. <a href="user.php?action=invite&amp;userid=<?=$UserID?>" class="brackets">Invites</a>
  204. <?
  205. }
  206. if (check_perms('admin_manage_permissions', $Class)) {
  207. ?>
  208. <a href="user.php?action=permissions&amp;userid=<?=$UserID?>" class="brackets">Permissions</a>
  209. <?
  210. }
  211. if (check_perms('users_view_ips', $Class)) {
  212. ?>
  213. <a href="user.php?action=sessions&amp;userid=<?=$UserID?>" class="brackets">Sessions</a>
  214. <?
  215. }
  216. if (check_perms('admin_reports')) {
  217. ?>
  218. <a href="reportsv2.php?view=reporter&amp;id=<?=$UserID?>" class="brackets">Reports</a>
  219. <?
  220. }
  221. if (check_perms('users_mod')) {
  222. ?>
  223. <a href="userhistory.php?action=token_history&amp;userid=<?=$UserID?>" class="brackets">FL tokens</a>
  224. <?
  225. }
  226. if (check_perms('admin_clear_cache') && check_perms('users_override_paranoia')) {
  227. ?>
  228. <a href="user.php?action=clearcache&amp;id=<?=$UserID?>" class="brackets">Clear cache</a>
  229. <?
  230. }
  231. if (check_perms('users_mod')) {
  232. ?>
  233. <a href="#staff_tools" class="brackets">Jump to staff tools</a>
  234. <?
  235. }
  236. ?>
  237. </div>
  238. <div class="sidebar">
  239. <?
  240. if ($Avatar && Users::has_avatars_enabled()) {
  241. ?>
  242. <div class="box box_image box_image_avatar">
  243. <div class="head colhead_dark">User</div>
  244. <div align="center">
  245. <?= Users::show_avatar($Avatar, $UserID, $Username, $HeavyInfo['DisableAvatars'])?>
  246. </div>
  247. </div>
  248. <? }
  249. $Badges = Badges::get_badges($UserID);
  250. if (!empty($Badges)) { ?>
  251. <div class="box">
  252. <div class="head colhead_dark">Badges</div>
  253. <div class="pad">
  254. <?=Badges::display_badges($Badges, true)?>
  255. </div>
  256. </div>
  257. <?
  258. }
  259. if (!$OwnProfile && !$LoggedUser['DisablePoints']) { ?>
  260. <div class='box point_gift_box'>
  261. <div class='head colhead_dark'>Send <?=BONUS_POINTS?></div>
  262. <div class="pad">
  263. <form action='user.php' method='post'>
  264. <input type='hidden' name='action' value='points' />
  265. <input type='hidden' name='to' value='<?=$UserID?>' />
  266. <input type='text' name='amount' placeholder='Amount' /><input type='submit' value='Send' /><br>
  267. <textarea name='message' rows='2' placeholder='Message'></textarea><br>
  268. <input type='checkbox' name='adjust' /> Adjust for tax?
  269. </form>
  270. <p>Note: 10% of your gift is taken as tax.</p>
  271. </div>
  272. </div>
  273. <?
  274. }
  275. $DB->query("
  276. SELECT u.Username
  277. FROM slaves AS s
  278. LEFT JOIN users_main AS u ON u.ID = s.OwnerID
  279. WHERE s.UserID = $UserID");
  280. if ($LoggedUser['Class'] >= 200 || $DB->has_results()) { ?>
  281. <div class='box ownership_box'>
  282. <div class='head colhead_dark'>Ownership</div>
  283. <div class="pad">
  284. <? if ($DB->has_results()) { ?>
  285. <p>This user is owned by <?=($DB->next_record()['Username'])?></p>
  286. <? } else {
  287. $DB->query("
  288. SELECT u.Uploaded, u.Downloaded, u.BonusPoints, COUNT(t.UserID)
  289. FROM users_main AS u
  290. LEFT JOIN torrents AS t ON u.ID=t.UserID
  291. WHERE u.ID = $UserID");
  292. list($Upload, $Download, $Points, $Uploads) = $DB->next_record();
  293. $Level = intval(((($Uploads**0.35)*1.5)+1) * max(($Upload+($Points*1000000)-$Download)/(1024**3), 1));
  294. ?>
  295. <p>This user is wild and level <?=$Level?></p>
  296. <? if (!$OwnProfile) { ?>
  297. <p>Try to capture them with <?=BONUS_POINTS?>? The more you spend, the higher the chance of capture</p>
  298. <form action='store.php' method='post'>
  299. <input type='hidden' name='item' value='capture_user' />
  300. <input type='hidden' name='target' value='<?=$UserID?>' />
  301. <input type='text' name='amount' placeholder='<?=BONUS_POINTS?>' /><input type='submit' value='Capture' />
  302. </form>
  303. <? }
  304. } ?>
  305. </div>
  306. </div>
  307. <? } ?>
  308. <div class="box box_info box_userinfo_stats">
  309. <div class="head colhead_dark">Statistics</div>
  310. <ul class="stats nobullet">
  311. <li>Joined: <?=$JoinedDate?></li>
  312. <? if (($Override = check_paranoia_here('lastseen'))) { ?>
  313. <li<?=($Override === 2 ? ' class="paranoia_override"' : '')?>>Last seen: <?=$LastAccess?></li>
  314. <?
  315. }
  316. if (($Override = check_paranoia_here('uploaded'))) {
  317. ?>
  318. <li class="tooltip<?=($Override === 2 ? ' paranoia_override' : '')?>" title="<?=Format::get_size($Uploaded, 5)?>">Uploaded: <?=Format::get_size($Uploaded)?></li>
  319. <?
  320. }
  321. if (($Override = check_paranoia_here('downloaded'))) {
  322. ?>
  323. <li class="tooltip<?=($Override === 2 ? ' paranoia_override' : '')?>" title="<?=Format::get_size($Downloaded, 5)?>">Downloaded: <?=Format::get_size($Downloaded)?></li>
  324. <?
  325. }
  326. if (($Override = check_paranoia_here('ratio'))) {
  327. ?>
  328. <li<?=($Override === 2 ? ' class="paranoia_override"' : '')?>>Ratio: <?=Format::get_ratio_html($Uploaded, $Downloaded)?></li>
  329. <?
  330. }
  331. if (($Override = check_paranoia_here('requiredratio')) && isset($RequiredRatio)) {
  332. ?>
  333. <li<?=($Override === 2 ? ' class="paranoia_override"' : '')?>>Required Ratio: <span class="tooltip" title="<?=number_format((double)$RequiredRatio, 5)?>"><?=number_format((double)$RequiredRatio, 2)?></span></li>
  334. <?
  335. }
  336. if ($OwnProfile || ($Override = check_paranoia_here(false)) || check_perms('users_mod')) {
  337. ?>
  338. <li<?=($Override === 2 ? ' class="paranoia_override"' : '')?>><a href="userhistory.php?action=token_history&amp;userid=<?=$UserID?>">Tokens</a>: <?=number_format($FLTokens)?></li>
  339. <?
  340. }
  341. if (($OwnProfile || check_perms('users_mod')) && $Warned != '0000-00-00 00:00:00') {
  342. ?>
  343. <li<?=($Override === 2 ? ' class="paranoia_override"' : '')?>>Warning expires in: <?=time_diff((date('Y-m-d H:i', strtotime($Warned))))?></li>
  344. <? } ?>
  345. </ul>
  346. </div>
  347. <?
  348. if (check_paranoia_here('requestsfilled_count') || check_paranoia_here('requestsfilled_bounty')) {
  349. $DB->query("
  350. SELECT
  351. COUNT(DISTINCT r.ID),
  352. SUM(rv.Bounty)
  353. FROM requests AS r
  354. LEFT JOIN requests_votes AS rv ON r.ID = rv.RequestID
  355. WHERE r.FillerID = $UserID");
  356. list($RequestsFilled, $TotalBounty) = $DB->next_record();
  357. } else {
  358. $RequestsFilled = $TotalBounty = 0;
  359. }
  360. if (check_paranoia_here('requestsvoted_count') || check_paranoia_here('requestsvoted_bounty')) {
  361. $DB->query("
  362. SELECT COUNT(RequestID), SUM(Bounty)
  363. FROM requests_votes
  364. WHERE UserID = $UserID");
  365. list($RequestsVoted, $TotalSpent) = $DB->next_record();
  366. $DB->query("
  367. SELECT COUNT(r.ID), SUM(rv.Bounty)
  368. FROM requests AS r
  369. LEFT JOIN requests_votes AS rv ON rv.RequestID = r.ID AND rv.UserID = r.UserID
  370. WHERE r.UserID = $UserID");
  371. list($RequestsCreated, $RequestsCreatedSpent) = $DB->next_record();
  372. } else {
  373. $RequestsVoted = $TotalSpent = $RequestsCreated = $RequestsCreatedSpent = 0;
  374. }
  375. if (check_paranoia_here('uploads+')) {
  376. $DB->query("
  377. SELECT COUNT(ID)
  378. FROM torrents
  379. WHERE UserID = '$UserID'");
  380. list($Uploads) = $DB->next_record();
  381. } else {
  382. $Uploads = 0;
  383. }
  384. if (check_paranoia_here('artistsadded')) {
  385. $DB->query("
  386. SELECT COUNT(DISTINCT ArtistID)
  387. FROM torrents_artists
  388. WHERE UserID = $UserID");
  389. list($ArtistsAdded) = $DB->next_record();
  390. } else {
  391. $ArtistsAdded = 0;
  392. }
  393. //Do the ranks
  394. $UploadedRank = UserRank::get_rank('uploaded', $Uploaded);
  395. $DownloadedRank = UserRank::get_rank('downloaded', $Downloaded);
  396. $UploadsRank = UserRank::get_rank('uploads', $Uploads);
  397. $RequestRank = UserRank::get_rank('requests', $RequestsFilled);
  398. $PostRank = UserRank::get_rank('posts', $ForumPosts);
  399. $BountyRank = UserRank::get_rank('bounty', $TotalSpent);
  400. $ArtistsRank = UserRank::get_rank('artists', $ArtistsAdded);
  401. if ($Downloaded == 0) {
  402. $Ratio = 1;
  403. } elseif ($Uploaded == 0) {
  404. $Ratio = 0.5;
  405. } else {
  406. $Ratio = round($Uploaded / $Downloaded, 2);
  407. }
  408. $OverallRank = UserRank::overall_score($UploadedRank, $DownloadedRank, $UploadsRank, $RequestRank, $PostRank, $BountyRank, $ArtistsRank, $Ratio);
  409. ?>
  410. <div class="box box_info box_userinfo_percentile">
  411. <div class="head colhead_dark">Percentile Rankings (hover for values)</div>
  412. <ul class="stats nobullet">
  413. <? if (($Override = check_paranoia_here('uploaded'))) { ?>
  414. <li class="tooltip<?=($Override === 2 ? ' paranoia_override' : '')?>" title="<?=Format::get_size($Uploaded)?>">Data uploaded: <?=$UploadedRank === false ? 'Server busy' : number_format($UploadedRank)?></li>
  415. <?
  416. }
  417. if (($Override = check_paranoia_here('downloaded'))) { ?>
  418. <li class="tooltip<?=($Override === 2 ? ' paranoia_override' : '')?>" title="<?=Format::get_size($Downloaded)?>">Data downloaded: <?=$DownloadedRank === false ? 'Server busy' : number_format($DownloadedRank)?></li>
  419. <?
  420. }
  421. if (($Override = check_paranoia_here('uploads+'))) { ?>
  422. <li class="tooltip<?=($Override === 2 ? ' paranoia_override' : '')?>" title="<?=number_format($Uploads)?>">Torrents uploaded: <?=$UploadsRank === false ? 'Server busy' : number_format($UploadsRank)?></li>
  423. <?
  424. }
  425. if (($Override = check_paranoia_here('requestsfilled_count'))) { ?>
  426. <li class="tooltip<?=($Override === 2 ? ' paranoia_override' : '')?>" title="<?=number_format($RequestsFilled)?>">Requests filled: <?=$RequestRank === false ? 'Server busy' : number_format($RequestRank)?></li>
  427. <?
  428. }
  429. if (($Override = check_paranoia_here('requestsvoted_bounty'))) { ?>
  430. <li class="tooltip<?=($Override === 2 ? ' paranoia_override' : '')?>" title="<?=Format::get_size($TotalSpent)?>">Bounty spent: <?=$BountyRank === false ? 'Server busy' : number_format($BountyRank)?></li>
  431. <? } ?>
  432. <li class="tooltip" title="<?=number_format($ForumPosts)?>">Posts made: <?=$PostRank === false ? 'Server busy' : number_format($PostRank)?></li>
  433. <? if (($Override = check_paranoia_here('artistsadded'))) { ?>
  434. <li class="tooltip<?=($Override === 2 ? ' paranoia_override' : '')?>" title="<?=number_format($ArtistsAdded)?>">Artists added: <?=$ArtistsRank === false ? 'Server busy' : number_format($ArtistsRank)?></li>
  435. <?
  436. }
  437. if (check_paranoia_here(array('uploaded', 'downloaded', 'uploads+', 'requestsfilled_count', 'requestsvoted_bounty', 'artistsadded'))) { ?>
  438. <li><strong>Overall rank: <?=$OverallRank === false ? 'Server busy' : number_format($OverallRank)?></strong></li>
  439. <? } ?>
  440. </ul>
  441. </div>
  442. <?
  443. if (check_perms('users_mod', $Class) || check_perms('users_view_ips', $Class) || check_perms('users_view_keys', $Class)) {
  444. $DB->query("
  445. SELECT COUNT(*)
  446. FROM users_history_passwords
  447. WHERE UserID = '$UserID'");
  448. list($PasswordChanges) = $DB->next_record();
  449. if (check_perms('users_view_keys', $Class)) {
  450. $DB->query("
  451. SELECT COUNT(*)
  452. FROM users_history_passkeys
  453. WHERE UserID = '$UserID'");
  454. list($PasskeyChanges) = $DB->next_record();
  455. }
  456. if (check_perms('users_view_ips', $Class)) {
  457. $DB->query("
  458. SELECT COUNT(DISTINCT IP)
  459. FROM users_history_ips
  460. WHERE UserID = '$UserID'");
  461. list($IPChanges) = $DB->next_record();
  462. $DB->query("
  463. SELECT COUNT(DISTINCT IP)
  464. FROM xbt_snatched
  465. WHERE uid = '$UserID'
  466. AND IP != ''");
  467. list($TrackerIPs) = $DB->next_record();
  468. }
  469. if (check_perms('users_view_email', $Class)) {
  470. $DB->query("
  471. SELECT COUNT(*)
  472. FROM users_history_emails
  473. WHERE UserID = '$UserID'");
  474. list($EmailChanges) = $DB->next_record();
  475. }
  476. ?>
  477. <div class="box box_info box_userinfo_history">
  478. <div class="head colhead_dark">History</div>
  479. <ul class="stats nobullet">
  480. <? if (check_perms('users_view_email', $Class)) { ?>
  481. <li>Emails: <?=number_format($EmailChanges)?> <a href="userhistory.php?action=email2&amp;userid=<?=$UserID?>" class="brackets">View</a>&nbsp;<a href="userhistory.php?action=email&amp;userid=<?=$UserID?>" class="brackets">Legacy view</a></li>
  482. <?
  483. }
  484. if (check_perms('users_view_ips', $Class)) {
  485. ?>
  486. <li>IPs: <?=number_format($IPChanges)?> <a href="userhistory.php?action=ips&amp;userid=<?=$UserID?>" class="brackets">View</a>&nbsp;<a href="userhistory.php?action=ips&amp;userid=<?=$UserID?>&amp;usersonly=1" class="brackets">View users</a></li>
  487. <? if (check_perms('users_view_ips', $Class) && check_perms('users_mod', $Class)) { ?>
  488. <li>Tracker IPs: <?=number_format($TrackerIPs)?> <a href="userhistory.php?action=tracker_ips&amp;userid=<?=$UserID?>" class="brackets">View</a></li>
  489. <?
  490. }
  491. }
  492. if (check_perms('users_view_keys', $Class)) {
  493. ?>
  494. <li>Passkeys: <?=number_format($PasskeyChanges)?> <a href="userhistory.php?action=passkeys&amp;userid=<?=$UserID?>" class="brackets">View</a></li>
  495. <?
  496. }
  497. if (check_perms('users_mod', $Class)) {
  498. ?>
  499. <li>Passwords: <?=number_format($PasswordChanges)?> <a href="userhistory.php?action=passwords&amp;userid=<?=$UserID?>" class="brackets">View</a></li>
  500. <li>Stats: N/A <a href="userhistory.php?action=stats&amp;userid=<?=$UserID?>" class="brackets">View</a></li>
  501. <? } ?>
  502. </ul>
  503. </div>
  504. <? } ?>
  505. <div class="box box_info box_userinfo_personal">
  506. <div class="head colhead_dark">Personal</div>
  507. <ul class="stats nobullet">
  508. <li>Class: <?=$ClassLevels[$Class]['Name']?></li>
  509. <?
  510. $UserInfo = Users::user_info($UserID);
  511. if (!empty($UserInfo['ExtraClasses'])) {
  512. ?>
  513. <li>
  514. <ul class="stats">
  515. <?
  516. foreach ($UserInfo['ExtraClasses'] as $PermID => $Val) {
  517. ?>
  518. <li><?=$Classes[$PermID]['Name']?></li>
  519. <? } ?>
  520. </ul>
  521. </li>
  522. <?
  523. }
  524. // An easy way for people to measure the paranoia of a user, for e.g. contest eligibility
  525. if ($ParanoiaLevel == 0) {
  526. $ParanoiaLevelText = 'Off';
  527. } elseif ($ParanoiaLevel == 1) {
  528. $ParanoiaLevelText = 'Very Low';
  529. } elseif ($ParanoiaLevel <= 5) {
  530. $ParanoiaLevelText = 'Low';
  531. } elseif ($ParanoiaLevel <= 20) {
  532. $ParanoiaLevelText = 'High';
  533. } else {
  534. $ParanoiaLevelText = 'Very high';
  535. }
  536. ?>
  537. <li>Paranoia level: <span class="tooltip" title="<?=$ParanoiaLevel?>"><?=$ParanoiaLevelText?></span></li>
  538. <? if (check_perms('users_view_email', $Class) || $OwnProfile) { ?>
  539. <li>Email: <a href="mailto:<?=display_str($Email)?>"><?=display_str($Email)?></a>
  540. <? if (check_perms('users_view_email', $Class)) { ?>
  541. <a href="user.php?action=search&amp;email_history=on&amp;email=<?=display_str($Email)?>" title="Search" class="brackets tooltip">S</a>
  542. <? } ?>
  543. </li>
  544. <? }
  545. if (check_perms('users_view_ips', $Class)) {
  546. $IP = apc_exists('DBKEY') ? DBCrypt::decrypt($IP) : '[Encrypted]';
  547. ?>
  548. <li>IP: <?=Tools::display_ip($IP)?></li>
  549. <li>Host: <?=Tools::get_host_by_ajax($IP)?></li>
  550. <?
  551. }
  552. if (check_perms('users_view_keys', $Class) || $OwnProfile) {
  553. ?>
  554. <li>Passkey: <a href="#" id="passkey" onclick="togglePassKey('<?=display_str($torrent_pass)?>'); return false;" class="brackets">View</a></li>
  555. <?
  556. }
  557. if (check_perms('users_view_invites')) {
  558. if (!$InviterID) {
  559. $Invited = '<span style="font-style: italic;">Nobody</span>';
  560. } else {
  561. $Invited = "<a href=\"user.php?id=$InviterID\">$InviterName</a>";
  562. }
  563. ?>
  564. <li>Invited by: <?=$Invited?></li>
  565. <li>Invites: <?
  566. $DB->query("
  567. SELECT COUNT(InviterID)
  568. FROM invites
  569. WHERE InviterID = '$UserID'");
  570. list($Pending) = $DB->next_record();
  571. if ($DisableInvites) {
  572. echo 'X';
  573. } else {
  574. echo number_format($Invites);
  575. }
  576. echo " ($Pending)"
  577. ?></li>
  578. <?
  579. }
  580. if (!isset($SupportFor)) {
  581. $DB->query('
  582. SELECT SupportFor
  583. FROM users_info
  584. WHERE UserID = '.$LoggedUser['ID']);
  585. list($SupportFor) = $DB->next_record();
  586. }
  587. if ($Override = check_perms('users_mod') || $OwnProfile || !empty($SupportFor)) {
  588. ?>
  589. <li<?=(($Override === 2 || $SupportFor) ? ' class="paranoia_override"' : '')?>>Clients: <?
  590. $DB->query("
  591. SELECT DISTINCT useragent
  592. FROM xbt_files_users
  593. WHERE uid = $UserID");
  594. $Clients = $DB->collect(0);
  595. echo implode('; ', $Clients);
  596. ?></li>
  597. <?
  598. }
  599. ?>
  600. </ul>
  601. </div>
  602. <?
  603. include(SERVER_ROOT.'/sections/user/community_stats.php');
  604. DonationsView::render_donor_stats($UserID);
  605. ?>
  606. </div>
  607. <div class="main_column">
  608. <?
  609. if ($RatioWatchEnds != '0000-00-00 00:00:00'
  610. && (time() < strtotime($RatioWatchEnds))
  611. && ($Downloaded * $RequiredRatio) > $Uploaded
  612. ) {
  613. ?>
  614. <div class="box">
  615. <div class="head">Ratio watch</div>
  616. <div class="pad">This user is currently on ratio watch and must upload <?=Format::get_size(($Downloaded * $RequiredRatio) - $Uploaded)?> in the next <?=time_diff($RatioWatchEnds)?>, or their leeching privileges will be revoked. Amount downloaded while on ratio watch: <?=Format::get_size($Downloaded - $RatioWatchDownload)?></div>
  617. </div>
  618. <?
  619. }
  620. ?>
  621. <div class="box">
  622. <div class="head">
  623. <?=!empty($InfoTitle) ? $InfoTitle : 'Profile';?>
  624. <span style="float: right;"><a toggle-target="#profilediv" toggle-replace="Show" class="brackets">Hide</a></span>&nbsp;
  625. </div>
  626. <div class="pad profileinfo" id="profilediv">
  627. <?
  628. if (!$Info) {
  629. ?>
  630. This profile is currently empty.
  631. <?
  632. } else {
  633. echo Text::full_format($Info);
  634. }
  635. ?>
  636. </div>
  637. </div>
  638. <?
  639. DonationsView::render_profile_rewards($EnabledRewards, $ProfileRewards);
  640. if (check_paranoia_here('snatched')) {
  641. $RecentSnatches = $Cache->get_value("recent_snatches_$UserID");
  642. if ($RecentSnatches === false) {
  643. $DB->query("
  644. SELECT
  645. g.ID,
  646. g.Name,
  647. g.WikiImage
  648. FROM xbt_snatched AS s
  649. INNER JOIN torrents AS t ON t.ID = s.fid
  650. INNER JOIN torrents_group AS g ON t.GroupID = g.ID
  651. WHERE s.uid = '$UserID'
  652. AND g.WikiImage != ''
  653. GROUP BY g.ID
  654. ORDER BY s.tstamp DESC
  655. LIMIT 5");
  656. $RecentSnatches = $DB->to_array();
  657. $Artists = Artists::get_artists($DB->collect('ID'));
  658. foreach ($RecentSnatches as $Key => $SnatchInfo) {
  659. $RecentSnatches[$Key]['Artist'] = Artists::display_artists($Artists[$SnatchInfo['ID']], false, true);
  660. }
  661. $Cache->cache_value("recent_snatches_$UserID", $RecentSnatches, 0); //inf cache
  662. }
  663. if (!empty($RecentSnatches)) {
  664. ?>
  665. <div class="box" id="recent_snatches">
  666. <div class="head">
  667. Recent Snatches
  668. <span style="float: right;"><a onclick="$('#recent_snatches_images').gtoggle(); this.innerHTML = (this.innerHTML == 'Hide' ? 'Show' : 'Hide'); wall('#recent_snatches_images', '.collage_image', [2,3]); return false;" class="brackets">Show</a></span>&nbsp;
  669. </div>
  670. <div id="recent_snatches_images" class="collage_images hidden">
  671. <? foreach ($RecentSnatches as $RS) { ?>
  672. <div style='width: 100px;' class='collage_image' >
  673. <a href="torrents.php?id=<?=$RS['ID']?>">
  674. <img class="tooltip" title="<?=display_str($RS['Artist'])?><?=display_str($RS['Name'])?>" src="<?=ImageTools::process($RS['WikiImage'], true)?>" alt="<?=display_str($RS['Artist'])?><?=display_str($RS['Name'])?>" width="100%" />
  675. </a>
  676. </div>
  677. <? } ?>
  678. </div>
  679. </div>
  680. <?
  681. }
  682. }
  683. if (check_paranoia_here('uploads')) {
  684. $RecentUploads = $Cache->get_value("recent_uploads_$UserID");
  685. if ($RecentUploads === false) {
  686. $DB->query("
  687. SELECT
  688. g.ID,
  689. g.Name,
  690. g.WikiImage
  691. FROM torrents_group AS g
  692. INNER JOIN torrents AS t ON t.GroupID = g.ID
  693. WHERE t.UserID = '$UserID'
  694. AND g.WikiImage != ''
  695. GROUP BY g.ID
  696. ORDER BY t.Time DESC
  697. LIMIT 5");
  698. $RecentUploads = $DB->to_array();
  699. $Artists = Artists::get_artists($DB->collect('ID'));
  700. foreach ($RecentUploads as $Key => $UploadInfo) {
  701. $RecentUploads[$Key]['Artist'] = Artists::display_artists($Artists[$UploadInfo['ID']], false, true);
  702. }
  703. $Cache->cache_value("recent_uploads_$UserID", $RecentUploads, 0); //inf cache
  704. }
  705. if (!empty($RecentUploads)) {
  706. ?>
  707. <div class="box" id="recent_uploads">
  708. <div class="head">
  709. Recent Uploads
  710. <span style="float: right;"><a onclick="$('#recent_uploads_images').gtoggle(); this.innerHTML = (this.innerHTML == 'Hide' ? 'Show' : 'Hide'); wall('#recent_uploads_images', '.collage_image', [2,3]); return false;" class="brackets">Show</a></span>&nbsp;
  711. </div>
  712. <div id="recent_uploads_images" class="collage_images hidden">
  713. <? foreach ($RecentUploads as $RU) { ?>
  714. <div style='width: 100px;' class='collage_image' >
  715. <a href="torrents.php?id=<?=$RU['ID']?>">
  716. <img class="tooltip" title="<?=$RU['Artist']?><?=$RU['Name']?>" src="<?=ImageTools::process($RU['WikiImage'], true)?>" alt="<?=$RU['Artist']?><?=$RU['Name']?>" width="100%" />
  717. </a>
  718. </div>
  719. <? } ?>
  720. </div>
  721. </div>
  722. <?
  723. }
  724. }
  725. $DB->query("
  726. SELECT ID, Name
  727. FROM collages
  728. WHERE UserID = '$UserID'
  729. AND CategoryID = '0'
  730. AND Deleted = '0'
  731. ORDER BY Featured DESC,
  732. Name ASC");
  733. $Collages = $DB->to_array(false, MYSQLI_NUM, false);
  734. $FirstCol = true;
  735. foreach ($Collages as $CollageInfo) {
  736. list($CollageID, $CName) = $CollageInfo;
  737. $DB->query("
  738. SELECT ct.GroupID,
  739. tg.WikiImage,
  740. tg.CategoryID
  741. FROM collages_torrents AS ct
  742. JOIN torrents_group AS tg ON tg.ID = ct.GroupID
  743. WHERE ct.CollageID = '$CollageID'
  744. ORDER BY ct.Sort
  745. LIMIT 5");
  746. $Collage = $DB->to_array(false, MYSQLI_ASSOC, false);
  747. ?>
  748. <div class="box" id="collage<?=$CollageID?>_box">
  749. <div class="head">
  750. <?=display_str($CName)?> - <a href="collages.php?id=<?=$CollageID?>" class="brackets">See full</a>
  751. <span style="float: right;">
  752. <a toggle-target="#collage<?=$CollageID?>_box .images" toggle-replace="<?=$FirstCol ? 'Show' : 'Hide' ?>" class="brackets"><?=$FirstCol ? 'Hide' : 'Show' ?></a>
  753. </span>
  754. </div>
  755. <div id="user_collage_images" class="collage_images">
  756. <? foreach ($Collage as $C) {
  757. $Group = Torrents::get_groups(array($C['GroupID']), true, true, false);
  758. extract(Torrents::array_group($Group[$C['GroupID']]));
  759. $Name = '';
  760. $Name .= Artists::display_artists($Artists, false, true);
  761. $Name .= $GroupName;
  762. ?>
  763. <div class="collage_image">
  764. <a href="torrents.php?id=<?=$GroupID?>">
  765. <img class="tooltip" title="<?=$Name?>" src="<?=ImageTools::process($C['WikiImage'], true)?>" alt="<?=$Name?>" width="100%" />
  766. </a>
  767. </div>
  768. <? } ?>
  769. </div>
  770. <script>
  771. $('#user_collage_images .collage_image img').load(function() {
  772. var test = true
  773. $('#user_collage_images .collage_image img').toArray().forEach(function(el) {
  774. if (!el.complete) test = false
  775. })
  776. if (test) wall('#user_collage_images', '.collage_image', 5)
  777. })
  778. wall('#user_collage_images','.collage_image',5)
  779. </script>
  780. </div>
  781. <?
  782. $FirstCol = false;
  783. }
  784. ?>
  785. <!-- for the "jump to staff tools" button -->
  786. <a id="staff_tools"></a>
  787. <?
  788. // Linked accounts
  789. if (check_perms('users_mod')) {
  790. include(SERVER_ROOT.'/sections/user/linkedfunctions.php');
  791. user_dupes_table($UserID);
  792. }
  793. if ((check_perms('users_view_invites')) && $Invited > 0) {
  794. include(SERVER_ROOT.'/classes/invite_tree.class.php');
  795. $Tree = new INVITE_TREE($UserID, array('visible' => false));
  796. ?>
  797. <div class="box" id="invitetree_box">
  798. <div class="head">
  799. Invite Tree <span style="float: right"><a toggle-target="#invitetree" class="brackets">Toggle</a></span>
  800. </div>
  801. <div id="invitetree" class="hidden">
  802. <? $Tree->make_tree(); ?>
  803. </div>
  804. </div>
  805. <?
  806. }
  807. if (check_perms('users_mod')) {
  808. DonationsView::render_donation_history(Donations::get_donation_history($UserID));
  809. }
  810. // Requests
  811. if (empty($LoggedUser['DisableRequests']) && check_paranoia_here('requestsvoted_list')) {
  812. $SphQL = new SphinxqlQuery();
  813. $SphQLResult = $SphQL->select('id, votes, bounty')
  814. ->from('requests, requests_delta')
  815. ->where('userid', $UserID)
  816. ->where('torrentid', 0)
  817. ->order_by('votes', 'desc')
  818. ->order_by('bounty', 'desc')
  819. ->limit(0, 100, 100) // Limit to 100 requests
  820. ->query();
  821. if ($SphQLResult->has_results()) {
  822. $SphRequests = $SphQLResult->to_array('id', MYSQLI_ASSOC);
  823. ?>
  824. <div class="box" id="requests_box">
  825. <div class="head">
  826. Requests <span style="float: right;"><a toggle-target="#requests" class="brackets">Show</a></span>
  827. </div>
  828. <div id="requests" class="hidden">
  829. <table cellpadding="6" cellspacing="1" border="0" width="100%">
  830. <tr class="colhead_dark">
  831. <td style="width: 48%;">
  832. <strong>Request Name</strong>
  833. </td>
  834. <td>
  835. <strong>Vote</strong>
  836. </td>
  837. <td>
  838. <strong>Bounty</strong>
  839. </td>
  840. <td>
  841. <strong>Added</strong>
  842. </td>
  843. </tr>
  844. <?
  845. $Requests = Requests::get_requests(array_keys($SphRequests));
  846. foreach ($SphRequests as $RequestID => $SphRequest) {
  847. $Request = $Requests[$RequestID];
  848. $VotesCount = $SphRequest['votes'];
  849. $Bounty = $SphRequest['bounty'] * 1024; // Sphinx stores bounty in kB
  850. $CategoryName = $Categories[$Request['CategoryID'] - 1];
  851. if ($CategoryName == 'Music') {
  852. $ArtistForm = Requests::get_artists($RequestID);
  853. $ArtistLink = Artists::display_artists($ArtistForm, true, true);
  854. $FullName = "$ArtistLink<a href=\"requests.php?action=view&amp;id=$RequestID\">$Request[Title] [$Request[Year]]</a>";
  855. } elseif ($CategoryName == 'Audiobooks' || $CategoryName == 'Comedy') {
  856. $FullName = "<a href=\"requests.php?action=view&amp;id=$RequestID\">$Request[Title] [$Request[Year]]</a>";
  857. } else {
  858. $FullName = "<a href=\"requests.php?action=view&amp;id=$RequestID\">$Request[Title]</a>";
  859. }
  860. ?>
  861. <tr class="row">
  862. <td>
  863. <?=$FullName ?>
  864. <div class="tags">
  865. <?
  866. $Tags = $Request['Tags'];
  867. $TagList = array();
  868. foreach ($Tags as $TagID => $TagName) {
  869. $TagList[] = "<a href=\"requests.php?tags=$TagName\">".display_str($TagName).'</a>';
  870. }
  871. $TagList = implode(', ', $TagList);
  872. ?>
  873. <?=$TagList?>
  874. </div>
  875. </td>
  876. <td>
  877. <span id="vote_count_<?=$RequestID?>"><?=$VotesCount?></span>
  878. <? if (check_perms('site_vote')) { ?>
  879. &nbsp;&nbsp; <a href="javascript:Vote(0, <?=$RequestID?>)" class="brackets">+</a>
  880. <? } ?>
  881. </td>
  882. <td>
  883. <span id="bounty_<?=$RequestID?>"><?=Format::get_size($Bounty)?></span>
  884. </td>
  885. <td>
  886. <?=time_diff($Request['TimeAdded']) ?>
  887. </td>
  888. </tr>
  889. <? } ?>
  890. </table>
  891. </div>
  892. </div>
  893. <?
  894. }
  895. }
  896. $IsFLS = isset($LoggedUser['ExtraClasses'][FLS_TEAM]);
  897. if (check_perms('users_mod', $Class) || $IsFLS) {
  898. $UserLevel = $LoggedUser['EffectiveClass'];
  899. $DB->query("
  900. SELECT
  901. SQL_CALC_FOUND_ROWS
  902. ID,
  903. Subject,
  904. Status,
  905. Level,
  906. AssignedToUser,
  907. Date,
  908. ResolverID
  909. FROM staff_pm_conversations
  910. WHERE UserID = $UserID
  911. AND (Level <= $UserLevel OR AssignedToUser = '".$LoggedUser['ID']."')
  912. ORDER BY Date DESC");
  913. if ($DB->has_results()) {
  914. $StaffPMs = $DB->to_array();
  915. ?>
  916. <div class="box" id="staffpms_box">
  917. <div class="head">
  918. Staff PMs <a toggle-target="#staffpms" class="brackets" style="float:right;">Toggle</a>
  919. </div>
  920. <table width="100%" class="message_table hidden" id="staffpms">
  921. <tr class="colhead">
  922. <td>Subject</td>
  923. <td>Date</td>
  924. <td>Assigned to</td>
  925. <td>Resolved by</td>
  926. </tr>
  927. <?
  928. foreach ($StaffPMs as $StaffPM) {
  929. list($ID, $Subject, $Status, $Level, $AssignedToUser, $Date, $ResolverID) = $StaffPM;
  930. // Get assigned
  931. if ($AssignedToUser == '') {
  932. // Assigned to class
  933. $Assigned = ($Level == 0) ? 'First Line Support' : $ClassLevels[$Level]['Name'];
  934. // No + on Sysops
  935. if ($Assigned != 'Sysop') {
  936. $Assigned .= '+';
  937. }
  938. } else {
  939. // Assigned to user
  940. $Assigned = Users::format_username($UserID, true, true, true, true);
  941. }
  942. if ($ResolverID) {
  943. $Resolver = Users::format_username($ResolverID, true, true, true, true);
  944. } else {
  945. $Resolver = '(unresolved)';
  946. }
  947. ?>
  948. <tr>
  949. <td><a href="staffpm.php?action=viewconv&amp;id=<?=$ID?>"><?=display_str($Subject)?></a></td>
  950. <td><?=time_diff($Date, 2, true)?></td>
  951. <td><?=$Assigned?></td>
  952. <td><?=$Resolver?></td>
  953. </tr>
  954. <? } ?>
  955. </table>
  956. </div>
  957. <?
  958. }
  959. }
  960. // Displays a table of forum warnings viewable only to Forum Moderators
  961. if ($LoggedUser['Class'] == 650 && check_perms('users_warn', $Class)) {
  962. $DB->query("
  963. SELECT Comment
  964. FROM users_warnings_forums
  965. WHERE UserID = '$UserID'");
  966. list($ForumWarnings) = $DB->next_record();
  967. if ($DB->has_results()) {
  968. ?>
  969. <div class="box">
  970. <div class="head">Forum warnings</div>
  971. <div class="pad">
  972. <div id="forumwarningslinks" class="AdminComment" style="width: 98%;"><?=Text::full_format($ForumWarnings)?></div>
  973. </div>
  974. </div>
  975. <?
  976. }
  977. }
  978. if (check_perms('users_mod', $Class)) { ?>
  979. <form class="manage_form" name="user" id="form" action="user.php" method="post">
  980. <input type="hidden" name="action" value="moderate" />
  981. <input type="hidden" name="userid" value="<?=$UserID?>" />
  982. <input type="hidden" name="auth" value="<?=$LoggedUser['AuthKey']?>" />
  983. <div class="box box2" id="staff_notes_box">
  984. <div class="head">
  985. Staff Notes
  986. <a href="#" name="admincommentbutton" onclick="ChangeTo('text'); return false;" class="brackets">Edit</a>
  987. <span style="float: right;">
  988. <a toggle-target="#staffnotes" class="brackets">Toggle</a>
  989. </span>
  990. </div>
  991. <div id="staffnotes" class="pad">
  992. <input type="hidden" name="comment_hash" value="<?=$CommentHash?>" />
  993. <div id="admincommentlinks" class="AdminComment" style="width: 98%;"><?=Text::full_format($AdminComment)?></div>
  994. <textarea id="admincomment" onkeyup="resize('admincomment');" class="AdminComment hidden" name="AdminComment" cols="65" rows="26" style="width: 98%;"><?=display_str($AdminComment)?></textarea>
  995. <a href="#" name="admincommentbutton" onclick="ChangeTo('text'); return false;" class="brackets">Toggle edit</a>
  996. <script type="text/javascript">
  997. resize('admincomment');
  998. </script>
  999. </div>
  1000. </div>
  1001. <table class="layout box" id="user_info_box">
  1002. <tr class="colhead">
  1003. <td colspan="2">
  1004. User Information
  1005. </td>
  1006. </tr>
  1007. <? if (check_perms('users_edit_usernames', $Class)) { ?>
  1008. <tr>
  1009. <td class="label">Username:</td>
  1010. <td><input type="text" size="20" name="Username" value="<?=display_str($Username)?>" /></td>
  1011. </tr>
  1012. <?
  1013. }
  1014. if (check_perms('users_edit_titles')) {
  1015. ?>
  1016. <tr>
  1017. <td class="label">Custom title:</td>
  1018. <td><input type="text" class="wide_input_text" name="Title" value="<?=display_str($CustomTitle)?>" /></td>
  1019. </tr>
  1020. <?
  1021. }
  1022. if (check_perms('users_promote_below', $Class) || check_perms('users_promote_to', $Class - 1)) {
  1023. ?>
  1024. <tr>
  1025. <td class="label">Primary class:</td>
  1026. <td>
  1027. <select name="Class">
  1028. <?
  1029. foreach ($ClassLevels as $CurClass) {
  1030. if (check_perms('users_promote_below', $Class) && $CurClass['ID'] >= $LoggedUser['EffectiveClass']) {
  1031. break;
  1032. }
  1033. if ($CurClass['ID'] > $LoggedUser['EffectiveClass']) {
  1034. break;
  1035. }
  1036. if ($CurClass['Secondary']) {
  1037. continue;
  1038. }
  1039. if ($Class === $CurClass['Level']) {
  1040. $Selected = ' selected="selected"';
  1041. } else {
  1042. $Selected = '';
  1043. }
  1044. ?>
  1045. <option value="<?=$CurClass['ID']?>"<?=$Selected?>><?=$CurClass['Name'].' ('.$CurClass['Level'].')'?></option>
  1046. <? } ?>
  1047. </select>
  1048. </td>
  1049. </tr>
  1050. <?
  1051. }
  1052. if (check_perms('users_give_donor')) {
  1053. ?>
  1054. <tr>
  1055. <td class="label">Donor:</td>
  1056. <td><input type="checkbox" name="Donor"<? if ($Donor == 1) { ?> checked="checked"<? } ?> /></td>
  1057. </tr>
  1058. <?
  1059. }
  1060. if (check_perms('users_promote_below') || check_perms('users_promote_to')) { ?>
  1061. <tr>
  1062. <td class="label">Secondary classes:</td>
  1063. <td>
  1064. <?
  1065. $DB->query("
  1066. SELECT p.ID, p.Name, l.UserID
  1067. FROM permissions AS p
  1068. LEFT JOIN users_levels AS l ON l.PermissionID = p.ID AND l.UserID = '$UserID'
  1069. WHERE p.Secondary = 1
  1070. ORDER BY p.Name");
  1071. $i = 0;
  1072. while (list($PermID, $PermName, $IsSet) = $DB->next_record()) {
  1073. $i++;
  1074. ?>
  1075. <input type="checkbox" id="perm_<?=$PermID?>" name="secondary_classes[]" value="<?=$PermID?>"<? if ($IsSet) { ?> checked="checked"<? } ?> />&nbsp;<label for="perm_<?=$PermID?>" style="margin-right: 10px;"><?=$PermName?></label>
  1076. <? if ($i % 3 == 0) {
  1077. echo "\t\t\t\t<br />\n";
  1078. }
  1079. } ?>
  1080. </td>
  1081. </tr>
  1082. <? }
  1083. if (check_perms('users_make_invisible')) {
  1084. ?>
  1085. <tr>
  1086. <td class="label">Visible in peer lists:</td>
  1087. <td><input type="checkbox" name="Visible"<? if ($Visible == 1) { ?> checked="checked"<? } ?> /></td>
  1088. </tr>
  1089. <?
  1090. }
  1091. if (check_perms('users_edit_ratio', $Class) || (check_perms('users_edit_own_ratio') && $UserID == $LoggedUser['ID'])) {
  1092. ?>
  1093. <tr>
  1094. <td class="label tooltip" title="Upload amount in bytes. Also accepts e.g. +20GB or -35.6364MB on the end.">Uploaded:</td>
  1095. <td>
  1096. <input type="hidden" name="OldUploaded" value="<?=$Uploaded?>" />
  1097. <input type="text" size="20" name="Uploaded" value="<?=$Uploaded?>" />
  1098. </td>
  1099. </tr>
  1100. <tr>
  1101. <td class="label tooltip" title="Download amount in bytes. Also accepts e.g. +20GB or -35.6364MB on the end.">Downloaded:</td>
  1102. <td>
  1103. <input type="hidden" name="OldDownloaded" value="<?=$Downloaded?>" />
  1104. <input type="text" size="20" name="Downloaded" value="<?=$Downloaded?>" />
  1105. </td>
  1106. </tr>
  1107. <tr>
  1108. <td class="label"><?=BONUS_POINTS?>:</td>
  1109. <td>
  1110. <input type="text" size="20" name="BonusPoints" value="<?=$BonusPoints?>" />
  1111. <?
  1112. if (!$DisablePoints) {
  1113. $PointsRate = 0.5;
  1114. $getTorrents = $DB->query("
  1115. SELECT COUNT(DISTINCT x.fid) AS Torrents,
  1116. SUM(t.Size) AS Size,
  1117. SUM(xs.seedtime) AS Seedtime,
  1118. SUM(t.Seeders) AS Seeders
  1119. FROM users_main AS um
  1120. LEFT JOIN users_info AS i on um.ID = i.UserID
  1121. LEFT JOIN xbt_files_users AS x ON um.ID=x.uid
  1122. LEFT JOIN torrents AS t ON t.ID=x.fid
  1123. LEFT JOIN xbt_snatched AS xs ON x.uid=xs.uid AND x.fid=xs.fid
  1124. WHERE
  1125. um.ID = $UserID
  1126. AND um.Enabled = '1'
  1127. AND x.active = 1
  1128. AND x.completed = 0
  1129. AND x.Remaining = 0
  1130. GROUP BY um.ID");
  1131. if ($DB->has_results()) {
  1132. list($NumTorr, $TSize, $TTime, $TSeeds) = $DB->next_record();
  1133. $PointsRate += (0.67*($NumTorr * (sqrt(($TSize/$NumTorr)/1073741824) * pow(1.5,($TTime/$NumTorr)/(24*365))))) / (max(1, sqrt(($TSeeds/$NumTorr)+4)/3));
  1134. }
  1135. $PointsRate = intval($PointsRate**0.95);
  1136. $PointsPerHour = number_format($PointsRate)." ".BONUS_POINTS."/hour";
  1137. $PointsPerDay = number_format($PointsRate*24)." ".BONUS_POINTS."/day";
  1138. } else {
  1139. $PointsPerHour = "0 ".BONUS_POINTS."/hour";
  1140. $PointsPerDay = BONUS_POINTS." disabled";
  1141. }
  1142. ?>
  1143. <?=$PointsPerHour?> (<?=$PointsPerDay?>)
  1144. </td>
  1145. </tr>
  1146. <tr>
  1147. <td class="label tooltip" title="Enter a username.">Merge stats <strong>from:</strong></td>
  1148. <td>
  1149. <input type="text" size="40" name="MergeStatsFrom" />
  1150. </td>
  1151. </tr>
  1152. <tr>
  1153. <td class="label">Freeleech tokens:</td>
  1154. <td>
  1155. <input type="text" size="5" name="FLTokens" value="<?=$FLTokens?>" />
  1156. </td>
  1157. </tr>
  1158. <?
  1159. }
  1160. if (check_perms('users_edit_invites')) {
  1161. ?>
  1162. <tr>
  1163. <td class="label tooltip" title="Number of invites">Invites:</td>
  1164. <td><input type="text" size="5" name="Invites" value="<?=$Invites?>" /></td>
  1165. </tr>
  1166. <?
  1167. }
  1168. if (check_perms('admin_manage_fls') || (check_perms('users_mod') && $OwnProfile)) {
  1169. ?>
  1170. <tr>
  1171. <td class="label tooltip" title="This is the message shown in the right-hand column on /staff.php">FLS/Staff remark:</td>
  1172. <td><input type="text" class="wide_input_text" name="SupportFor" value="<?=display_str($SupportFor)?>" /></td>
  1173. </tr>
  1174. <?
  1175. }
  1176. if (check_perms('users_edit_reset_keys')) {
  1177. ?>
  1178. <tr>
  1179. <td class="label">Reset:</td>
  1180. <td>
  1181. <input type="checkbox" name="ResetRatioWatch" id="ResetRatioWatch" /> <label for="ResetRatioWatch">Ratio watch</label> |
  1182. <input type="checkbox" name="ResetPasskey" id="ResetPasskey" /> <label for="ResetPasskey">Passkey</label> |
  1183. <input type="checkbox" name="ResetAuthkey" id="ResetAuthkey" /> <label for="ResetAuthkey">Authkey</label> |
  1184. <input type="checkbox" name="ResetIPHistory" id="ResetIPHistory" /> <label for="ResetIPHistory">IP history</label> |
  1185. <input type="checkbox" name="ResetEmailHistory" id="ResetEmailHistory" /> <label for="ResetEmailHistory">Email history</label>
  1186. <br />
  1187. <input type="checkbox" name="ResetSnatchList" id="ResetSnatchList" /> <label for="ResetSnatchList">Snatch list</label> |
  1188. <input type="checkbox" name="ResetDownloadList" id="ResetDownloadList" /> <label for="ResetDownloadList">Download list</label>
  1189. </td>
  1190. </tr>
  1191. <?
  1192. }
  1193. if (check_perms('users_edit_password')) {
  1194. ?>
  1195. <tr>
  1196. <td class="label">New password:</td>
  1197. <td>
  1198. <input type="text" size="30" id="change_password" name="ChangePassword" />
  1199. <button type="button" id="random_password">Generate</button>
  1200. </td>
  1201. </tr>
  1202. <? }
  1203. if (check_perms('users_edit_badges')) {
  1204. ?>
  1205. <tr id="user_badge_edit_tr">
  1206. <td class="label">Badges Owned:</td>
  1207. <td>
  1208. <?
  1209. $DB->query("
  1210. SELECT ID AS BadgeID, Icon, Name, Description
  1211. FROM badges");
  1212. if ($DB->has_results()) { //If the DB has no results here, something is dangerously fucked
  1213. $AllBadges = $DB->to_array();
  1214. $UserBadgeIDs = array();
  1215. foreach (Badges::get_badges($UserID) as $Badge) {
  1216. $UserBadgeIDs[] = $Badge['BadgeID'];
  1217. }
  1218. $i = 0;
  1219. foreach ($AllBadges as $Badge) {
  1220. ?><input type="checkbox" name="badges[]" class="badge_checkbox" value="<?=$Badge['BadgeID']?>" <?=(in_array($Badge['BadgeID'], $UserBadgeIDs))?" checked":""?>/><?=Badges::display_badge($Badge, true)?>
  1221. <? $i++;
  1222. if ($i % 8 == 0) {
  1223. echo "<br />";
  1224. }
  1225. }
  1226. }
  1227. ?>
  1228. </td>
  1229. </tr>
  1230. <? } ?>
  1231. </table>
  1232. <? if (check_perms('users_warn')) { ?>
  1233. <table class="layout box" id="warn_user_box">
  1234. <tr class="colhead">
  1235. <td colspan="2">
  1236. Warnings
  1237. </td>
  1238. </tr>
  1239. <tr>
  1240. <td class="label">Warned:</td>
  1241. <td>
  1242. <input type="checkbox" name="Warned"<? if ($Warned != '0000-00-00 00:00:00') { ?> checked="checked"<? } ?> />
  1243. </td>
  1244. </tr>
  1245. <? if ($Warned == '0000-00-00 00:00:00') { // user is not warned ?>
  1246. <tr>
  1247. <td class="label">Expiration:</td>
  1248. <td>
  1249. <select name="WarnLength">
  1250. <option value="">---</option>
  1251. <option value="1">1 week</option>
  1252. <option value="2">2 weeks</option>
  1253. <option value="4">4 weeks</option>
  1254. <option value="8">8 weeks</option>
  1255. </select>
  1256. </td>
  1257. </tr>
  1258. <? } else { // user is warned ?>
  1259. <tr>
  1260. <td class="label">Extension:</td>
  1261. <td>
  1262. <select name="ExtendWarning" onchange="ToggleWarningAdjust(this);">
  1263. <option>---</option>
  1264. <option value="1">1 week</option>
  1265. <option value="2">2 weeks</option>
  1266. <option value="4">4 weeks</option>
  1267. <option value="8">8 weeks</option>
  1268. </select>
  1269. </td>
  1270. </tr>
  1271. <tr id="ReduceWarningTR">
  1272. <td class="label">Reduction:</td>
  1273. <td>
  1274. <select name="ReduceWarning">
  1275. <option>---</option>
  1276. <option value="1">1 week</option>
  1277. <option value="2">2 weeks</option>
  1278. <option value="4">4 weeks</option>
  1279. <option value="8">8 weeks</option>
  1280. </select>
  1281. </td>
  1282. </tr>
  1283. <? } ?>
  1284. <tr>
  1285. <td class="label tooltip" title="This message *will* be sent to the user in the warning PM!">Warning reason:</td>
  1286. <td>
  1287. <input type="text" class="wide_input_text" name="WarnReason" />
  1288. </td>
  1289. </tr>
  1290. <? } ?>
  1291. </table>
  1292. <? if (check_perms('users_disable_any')) { ?>
  1293. <table class="layout box">
  1294. <tr class="colhead">
  1295. <td colspan="2">
  1296. Lock Account
  1297. </td>
  1298. </tr>
  1299. <tr>
  1300. <td class="label">Lock Account:</td>
  1301. <td>
  1302. <input type="checkbox" name="LockAccount" id="LockAccount" <? if($LockedAccount) { ?> checked="checked" <? } ?>/>
  1303. </td>
  1304. </tr>
  1305. <tr>
  1306. <td class="label">Reason:</td>
  1307. <td>
  1308. <select name="LockReason">
  1309. <option value="---">---</option>
  1310. <option value="<?=STAFF_LOCKED?>" <? if ($LockedAccount == STAFF_LOCKED) { ?> selected <? } ?>>Staff Lock</option>
  1311. </select>
  1312. </td>
  1313. </tr>
  1314. </table>
  1315. <? } ?>
  1316. <table class="layout box" id="user_privs_box">
  1317. <tr class="colhead">
  1318. <td colspan="2">
  1319. User Privileges
  1320. </td>
  1321. </tr>
  1322. <? if (check_perms('users_disable_posts') || check_perms('users_disable_any')) {
  1323. $DB->query("
  1324. SELECT DISTINCT Email, IP
  1325. FROM users_history_emails
  1326. WHERE UserID = $UserID
  1327. ORDER BY Time ASC");
  1328. $Emails = $DB->to_array();
  1329. ?>
  1330. <tr>
  1331. <td class="label">Disable:</td>
  1332. <td>
  1333. <input type="checkbox" name="DisablePosting" id="DisablePosting"<? if ($DisablePosting == 1) { ?> checked="checked"<? } ?> /> <label for="DisablePosting">Posting</label>
  1334. <? if (check_perms('users_disable_any')) { ?> |
  1335. <input type="checkbox" name="DisableAvatar" id="DisableAvatar"<? if ($DisableAvatar == 1) { ?> checked="checked"<? } ?> /> <label for="DisableAvatar">Avatar</label> |
  1336. <input type="checkbox" name="DisableForums" id="DisableForums"<? if ($DisableForums == 1) { ?> checked="checked"<? } ?> /> <label for="DisableForums">Forums</label> |
  1337. <input type="checkbox" name="DisableIRC" id="DisableIRC"<? if ($DisableIRC == 1) { ?> checked="checked"<? } ?> /> <label for="DisableIRC">IRC</label> |
  1338. <input type="checkbox" name="DisablePM" id="DisablePM"<? if ($DisablePM == 1) { ?> checked="checked"<? } ?> /> <label for="DisablePM">PM</label> |
  1339. <br /><br />
  1340. <input type="checkbox" name="DisableLeech" id="DisableLeech"<? if ($DisableLeech == 0) { ?> checked="checked"<? } ?> /> <label for="DisableLeech">Leech</label> |
  1341. <input type="checkbox" name="DisableRequests" id="DisableRequests"<? if ($DisableRequests == 1) { ?> checked="checked"<? } ?> /> <label for="DisableRequests">Requests</label> |
  1342. <input type="checkbox" name="DisableUpload" id="DisableUpload"<? if ($DisableUpload == 1) { ?> checked="checked"<? } ?> /> <label for="DisableUpload">Torrent upload</label> |
  1343. <input type="checkbox" name="DisablePoints" id="DisablePoints"<? if ($DisablePoints == 1) { ?> checked="checked"<? } ?> /> <label for="DisablePoints"><?=BONUS_POINTS?></label>
  1344. <br /><br />
  1345. <input type="checkbox" name="DisableTagging" id="DisableTagging"<? if ($DisableTagging == 1) { ?> checked="checked"<? } ?> /> <label for="DisableTagging" class="tooltip" title="This only disables a user's ability to delete tags.">Tagging</label> |
  1346. <input type="checkbox" name="DisableWiki" id="DisableWiki"<? if ($DisableWiki == 1) { ?> checked="checked"<? } ?> /> <label for="DisableWiki">Wiki</label> |
  1347. <input type="checkbox" name="DisablePromotion" id="DisablePromotion"<? if ($DisablePromotion == 1) { ?> checked="checked"<? } ?> /> <label for="DisablePromotion">Promotions</label> |
  1348. <input type="checkbox" name="DisableInvites" id="DisableInvites"<? if ($DisableInvites == 1) { ?> checked="checked"<? } ?> /> <label for="DisableInvites">Invites</label>
  1349. </td>
  1350. </tr>
  1351. <tr>
  1352. <td class="label">Hacked:</td>
  1353. <td>
  1354. <input type="checkbox" name="SendHackedMail" id="SendHackedMail" /> <label for="SendHackedMail">Send hacked account email</label> to
  1355. <select name="HackedEmail">
  1356. <?
  1357. foreach ($Emails as $Email) {
  1358. list($Address, $IP) = $Email;
  1359. $IP = apc_exists('DBKEY') ? DBCrypt::decrypt($IP) : '[Encrypted]';
  1360. $Address = apc_exists('DBKEY') ? DBCrypt::decrypt($Address) : '[Encrypted]';
  1361. ?>
  1362. <option value="<?=display_str($Address)?>"><?=display_str($Address)?> - <?=display_str($IP)?></option>
  1363. <? } ?>
  1364. </select>
  1365. </td>
  1366. </tr>
  1367. <?
  1368. }
  1369. }
  1370. if (check_perms('users_disable_any')) {
  1371. ?>
  1372. <tr>
  1373. <td class="label">Account:</td>
  1374. <td>
  1375. <select name="UserStatus">
  1376. <option value="0"<? if ($Enabled == '0') { ?> selected="selected"<? } ?>>Unconfirmed</option>
  1377. <option value="1"<? if ($Enabled == '1') { ?> selected="selected"<? } ?>>Enabled</option>
  1378. <option value="2"<? if ($Enabled == '2') { ?> selected="selected"<? } ?>>Disabled</option>
  1379. <? if (check_perms('users_delete_users')) { ?>
  1380. <optgroup label="-- WARNING --">
  1381. <option value="delete">Delete account</option>
  1382. </optgroup>
  1383. <? } ?>
  1384. </select>
  1385. </td>
  1386. </tr>
  1387. <tr>
  1388. <td class="label">User reason:</td>
  1389. <td>
  1390. <input type="text" class="wide_input_text" name="UserReason" />
  1391. </td>
  1392. </tr>
  1393. <tr>
  1394. <td class="label tooltip" title="Enter a comma-delimited list of forum IDs.">Restricted forums:</td>
  1395. <td>
  1396. <input type="text" class="wide_input_text" name="RestrictedForums" value="<?=display_str($RestrictedForums)?>" />
  1397. </td>
  1398. </tr>
  1399. <tr>
  1400. <td class="label tooltip" title="Enter a comma-delimited list of forum IDs.">Extra forums:</td>
  1401. <td>
  1402. <input type="text" class="wide_input_text" name="PermittedForums" value="<?=display_str($PermittedForums)?>" />
  1403. </td>
  1404. </tr>
  1405. <? } ?>
  1406. </table>
  1407. <? if (check_perms('users_logout')) { ?>
  1408. <table class="layout box" id="session_box">
  1409. <tr class="colhead">
  1410. <td colspan="2">
  1411. Session
  1412. </td>
  1413. </tr>
  1414. <tr>
  1415. <td class="label">Reset session:</td>
  1416. <td><input type="checkbox" name="ResetSession" id="ResetSession" /></td>
  1417. </tr>
  1418. <tr>
  1419. <td class="label">Log out:</td>
  1420. <td><input type="checkbox" name="LogOut" id="LogOut" /></td>
  1421. </tr>
  1422. </table>
  1423. <?
  1424. }
  1425. if (check_perms('users_mod')) {
  1426. DonationsView::render_mod_donations($UserID);
  1427. }
  1428. ?>
  1429. <table class="layout box" id="submit_box">
  1430. <tr class="colhead">
  1431. <td colspan="2">
  1432. Submit
  1433. </td>
  1434. </tr>
  1435. <tr>
  1436. <td class="label tooltip" title="This message will be entered into staff notes only.">Reason:</td>
  1437. <td>
  1438. <textarea rows="1" cols="35" class="wide_input_text" name="Reason" id="Reason" onkeyup="resize('Reason');"></textarea>
  1439. </td>
  1440. </tr>
  1441. <tr>
  1442. <td class="label">Paste user stats:</td>
  1443. <td>
  1444. <button type="button" id="paster">Paste</button>
  1445. </td>
  1446. </tr>
  1447. <tr>
  1448. <td align="right" colspan="2">
  1449. <input type="submit" value="Save changes" />
  1450. </td>
  1451. </tr>
  1452. </table>
  1453. </form>
  1454. <?
  1455. }
  1456. ?>
  1457. </div>
  1458. </div>
  1459. <script>
  1460. $('.tooltip').tooltipster();
  1461. </script>
  1462. <? View::show_footer(); ?>