user_info.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. <?php
  2. $username = $_GET['username'];
  3. requireLib('flot');
  4. $REQUIRE_LIB['mathjax'] = '';
  5. $REQUIRE_LIB['hljs'] = '';
  6. ?>
  7. <?php if (validateUsername($username) && ($user = queryUser($username))): ?>
  8. <?php echoUOJPageHeader($user['username'] . ' - ' . UOJLocale::get('user profile')) ?>
  9. <?php
  10. $esc_email = HTML::escape($user['email']);
  11. $esc_qq = HTML::escape($user['qq'] != 0 ? $user['qq'] : 'Unfilled');
  12. $esc_sex = HTML::escape($user['sex']);
  13. $col_sex="color:blue";
  14. if ($esc_sex == "M") {
  15. $esc_sex="♂";
  16. $col_sex="color:blue";
  17. } elseif ($esc_sex == "F") {
  18. $esc_sex="♀";
  19. $col_sex="color:red";
  20. } else {
  21. $esc_sex="";
  22. $col_sex="color:black";
  23. }
  24. $esc_motto = HTML::escape($user['motto']);
  25. $extgroups = $user['extgroups'];
  26. ?>
  27. <div class="card border-info">
  28. <h5 class="card-header bg-info"><?= UOJLocale::get('user profile') ?></h5>
  29. <div class="card-body">
  30. <div class="row mb-4">
  31. <div class="col-md-4 order-md-9">
  32. <img class="media-object img-thumbnail d-block mx-auto" alt="<?= $user['username'] ?> Avatar" height="250" width="250" src="<?= HTML::avatar_addr($user, 256) ?>" />
  33. </div>
  34. <div class="col-md-8 order-md-1">
  35. <h2><span class="uoj-honor" data-rating="<?= $user['rating'] ?>" data-certs="<?= $user['certs'] ?>"><?= $user['username'] ?></span> <span><strong style="<?= $col_sex ?>"><?= $esc_sex ?></strong></span></h2>
  36. <div class="list-group">
  37. <div class="list-group-item">
  38. <h4 class="list-group-item-heading"><?= UOJLocale::get('rating') ?></h4>
  39. <p class="list-group-item-text"><strong style="color:red"><?= $user['rating'] ?></strong></p>
  40. </div>
  41. <div class="list-group-item">
  42. <h4 class="list-group-item-heading"><?= UOJLocale::get('email') ?></h4>
  43. <p class="list-group-item-text"><?= $esc_email ?></p>
  44. </div>
  45. <div class="list-group-item">
  46. <h4 class="list-group-item-heading"><?= UOJLocale::get('QQ') ?></h4>
  47. <p class="list-group-item-text"><?= $esc_qq ?></p>
  48. </div>
  49. <div class="list-group-item">
  50. <h4 class="list-group-item-heading"><?= UOJLocale::get('motto') ?></h4>
  51. <p class="list-group-item-text"><?= $esc_motto ?></p>
  52. </div>
  53. <div class="list-group-item">
  54. <h4 class="list-group-item-heading">用户组信息</h4>
  55. <p class="list-group-item-text"><?= $extgroups ?></p>
  56. </div>
  57. <?php if (isSuperUser($myUser)): ?>
  58. <div class="list-group-item">
  59. <h4 class="list-group-item-heading">register time</h4>
  60. <p class="list-group-item-text"><?= $user['register_time'] ?></p>
  61. </div>
  62. <div class="list-group-item">
  63. <h4 class="list-group-item-heading">remote_addr</h4>
  64. <p class="list-group-item-text"><?= $user['remote_addr'] ?></p>
  65. </div>
  66. <div class="list-group-item">
  67. <h4 class="list-group-item-heading">http_x_forwarded_for</h4>
  68. <p class="list-group-item-text"><?= $user['http_x_forwarded_for'] ?></p>
  69. </div>
  70. <?php endif ?>
  71. </div>
  72. </div>
  73. </div>
  74. <?php if (Auth::check()): ?>
  75. <?php if (Auth::id() != $user['username']): ?>
  76. <a type="button" class="btn btn-info btn-sm" href="/user/msg?enter=<?= $user['username'] ?>"><span class="glyphicon glyphicon-envelope"></span> <?= UOJLocale::get('send private message') ?></a>
  77. <?php else: ?>
  78. <a type="button" class="btn btn-info btn-sm" href="/user/modify-profile"><span class="glyphicon glyphicon-pencil"></span> <?= UOJLocale::get('modify my profile') ?></a>
  79. <?php endif ?>
  80. <?php endif ?>
  81. <a type="button" class="btn btn-success btn-sm" href="<?= HTML::blog_url($user['username'], '/') ?>"><span class="glyphicon glyphicon-arrow-right"></span> <?= UOJLocale::get('visit his blog', $username) ?></a>
  82. <div class="top-buffer-lg"></div>
  83. <div class="list-group">
  84. <?php
  85. $blogid = $user['aboutme_blogid'];
  86. if ($blogid) {
  87. echo '<div class="list-group-item">';
  88. echoBlog(queryBlog($blogid), array('show_content_only' => true, 'outside_blog_domain' => true));
  89. echo '</div>';
  90. }
  91. ?>
  92. <div class="list-group-item">
  93. <h4 class="list-group-item-heading"><?= UOJLocale::get('rating changes') ?></h4>
  94. <div class="list-group-item-text" id="rating-plot" style="height:500px;"></div>
  95. </div>
  96. <div class="list-group-item">
  97. <?php
  98. $ac_problems = DB::selectAll("select problem_id from best_ac_submissions where submitter = '{$user['username']}'");
  99. ?>
  100. <h4 class="list-group-item-heading"><?= UOJLocale::get('accepted problems').':'.UOJLocale::get('n problems in total', count($ac_problems))?> </h4>
  101. <p class="list-group-item-text">
  102. <?php
  103. foreach ($ac_problems as $problem) {
  104. echo '<a href="/problem/', $problem['problem_id'], '" style="display:inline-block; width:4em;">', $problem['problem_id'], '</a>';
  105. }
  106. if (empty($ac_problems)) {
  107. echo UOJLocale::get('none');
  108. }
  109. ?>
  110. </p>
  111. </div>
  112. </div>
  113. </div>
  114. </div>
  115. <script type="text/javascript">
  116. var rating_data = [[
  117. <?php
  118. $user_rating_min = $user_rating_max = 1500;
  119. $result = DB::query("select contest_id, `rank`, user_rating from contests_registrants where username = '{$user['username']}' and has_participated = 1 order by contest_id");
  120. $is_first_row = true;
  121. $last_rating = 1500;
  122. while ($row = DB::fetch($result)) {
  123. $contest = queryContest($row['contest_id']);
  124. $rating_delta = $row['user_rating'] - $last_rating;
  125. if (!$is_first_row) {
  126. echo "[$last_contest_time, {$row['user_rating']}, $last_contest_id, $last_contest_name, $last_rank, $rating_delta],";
  127. } else {
  128. $is_first_row = false;
  129. }
  130. $contest_start_time = new DateTime($contest['start_time']);
  131. $last_contest_time = ($contest_start_time->getTimestamp() + $contest_start_time->getOffset()) * 1000;
  132. $last_contest_name = json_encode($contest['name']);
  133. $last_contest_id = $contest['id'];
  134. $last_rank = $row['rank'];
  135. $last_rating = $row['user_rating'];
  136. if ($row['user_rating'] < $user_rating_min) {
  137. $user_rating_min = $row['user_rating'];
  138. }
  139. if ($row['user_rating'] > $user_rating_max) {
  140. $user_rating_max = $row['user_rating'];
  141. }
  142. }
  143. if ($is_first_row) {
  144. $time_now_stamp = (UOJTime::$time_now->getTimestamp() + UOJTime::$time_now->getOffset()) * 1000;
  145. echo "[{$time_now_stamp}, {$user['rating']}, 0]";
  146. } else {
  147. $rating_delta = $user['rating'] - $last_rating;
  148. echo "[$last_contest_time, {$user['rating']}, $last_contest_id, $last_contest_name, $last_rank, $rating_delta]";
  149. }
  150. if ($user['rating'] < $user_rating_min) {
  151. $user_rating_min = $user['rating'];
  152. }
  153. if ($user['rating'] > $user_rating_max) {
  154. $user_rating_max = $user['rating'];
  155. }
  156. $user_rating_min -= 400;
  157. $user_rating_max += 400;
  158. ?>
  159. ]];
  160. var rating_plot = $.plot($("#rating-plot"), [{
  161. color: "#3850eb",
  162. label: "<?= $user['username'] ?>",
  163. data: rating_data[0]
  164. }], {
  165. series: {
  166. lines: {
  167. show: true
  168. },
  169. points: {
  170. show: true
  171. }
  172. },
  173. xaxis: {
  174. mode: "time"
  175. },
  176. yaxis: {
  177. min: <?= $user_rating_min ?>,
  178. max: <?= $user_rating_max ?>
  179. },
  180. legend: {
  181. labelFormatter: function(username) {
  182. return getUserLink(username, <?= $user['rating'] ?>, false);
  183. }
  184. },
  185. grid: {
  186. clickable: true,
  187. hoverable: true
  188. },
  189. hooks: {
  190. drawBackground: [
  191. function(plot, ctx) {
  192. var plotOffset = plot.getPlotOffset();
  193. for (var y = 0; y < plot.height(); y++) {
  194. var rating = <?= $user_rating_max ?> - <?= $user_rating_max - $user_rating_min ?> * y / plot.height();
  195. ctx.fillStyle = getColOfRating(rating);
  196. ctx.fillRect(plotOffset.left, plotOffset.top + y, plot.width(), Math.min(5, plot.height() - y));
  197. }
  198. }
  199. ]
  200. }
  201. });
  202. function showTooltip(x, y, contents) {
  203. $('<div id="rating-tooltip">' + contents + '</div>').css({
  204. position: 'absolute',
  205. display: 'none',
  206. top: y - 20,
  207. left: x + 10,
  208. border: '1px solid #fdd',
  209. padding: '2px',
  210. 'font-size' : '11px',
  211. 'background-color': '#fee',
  212. opacity: 0.80
  213. }).appendTo("body").fadeIn(200);
  214. }
  215. var prev = -1;
  216. function onHoverRating(event, pos, item) {
  217. if (prev != item.dataIndex) {
  218. $("#rating-tooltip").remove();
  219. var params = rating_data[item.seriesIndex][item.dataIndex];
  220. var total = params[1];
  221. var contestId = params[2];
  222. if (contestId != 0) {
  223. var change = params[5] > 0 ? "+" + params[5] : params[5];
  224. var contestName = params[3];
  225. var rank = params[4];
  226. var html = "= " + total + " (" + change + "), <br/>"
  227. + "Rank: " + rank + "<br/>"
  228. + '<a href="' + '/contest/' + contestId + '">' + contestName + '</a>';
  229. } else {
  230. var html = "= " + total + "<br/>"
  231. + "Unrated";
  232. }
  233. showTooltip(item.pageX, item.pageY, html);
  234. prev = item.dataIndex;
  235. }
  236. }
  237. $("#rating-plot").bind("plothover", function (event, pos, item) {
  238. if (item) {
  239. onHoverRating(event, pos, item);
  240. }
  241. });
  242. $("#rating-plot").bind("plotclick", function (event, pos, item) {
  243. if (item && prev == -1) {
  244. onHoverRating(event, pos, item);
  245. } else {
  246. $("#rating-tooltip").fadeOut(200);
  247. prev = -1;
  248. }
  249. });
  250. </script>
  251. <?php else: ?>
  252. <?php echoUOJPageHeader('不存在该用户' . ' - 用户信息') ?>
  253. <div class="card border-danger">
  254. <div class="card-header bg-danger">用户信息</div>
  255. <div class="card-body">
  256. <h4>不存在该用户</h4>
  257. </div>
  258. </div>
  259. <?php endif ?>
  260. <?php echoUOJPageFooter() ?>