profile.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. <?php
  2. /**
  3. * User profile view.
  4. *
  5. * Contains the view layout and ome code to present the data.
  6. *
  7. * @author Iñigo Valentin <i@inigovalentin.com>
  8. * @license https://www.gnu.org/licenses/gpl-3.0.en.html GNU General Public License V3
  9. * @package SWDB
  10. * @category View
  11. * @property Profile_Page $page The page model.
  12. * @var Profile_Page $page The page model.
  13. */
  14. ?>
  15. <!DOCTYPE html>
  16. <html lang='en'>
  17. <head>
  18. <meta content='text/html; charset=utf-8' http-equiv='content-type'/>
  19. <meta name='viewport' content='width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1'/>
  20. <title><?=$page->get_title()?></title>
  21. <link rel='shortcut icon' href='<?=$page->get_favicon()?>'/>
  22. <!-- CSS files -->
  23. <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui.css'/>
  24. <?php
  25. if (get_context()->get_game_mode() == GAME_MODE_ID::RTA){
  26. ?>
  27. <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>ui-rta.css'/>
  28. <?php
  29. }
  30. ?>
  31. <link rel='stylesheet' type='text/css' href='<?=URL::CSS?>profile.css'/>
  32. <!-- Meta tags -->
  33. <link rel='canonical' href='<?=$page->get_canonical()?>'/>
  34. <link rel='author' href='<?=$page->get_author()?>'/>
  35. <link rel='publisher' href='<?=$page->get_author()?>'/>
  36. <meta name='description' content='<?=$page->get_description()?>'/>
  37. <meta property='og:title' content='<?=$page->get_title()?>'/>
  38. <meta property='og:url' content='<?=$page->get_canonical()?>'/>
  39. <meta property='og:description' content='<?=$page->get_description()?>'/>
  40. <meta property='og:image' content='<?=$page->get_icon()?>'/>
  41. <meta property='og:site_name' content='<?=$page->get_name()?>?>'/>
  42. <meta property='og:type' content='website'/>
  43. <meta property='og:locale' content='en'/>
  44. <meta name='twitter:card' content='summary'/>
  45. <meta name='twitter:title' content='<?=$page->get_title()?>'/>
  46. <meta name='twitter:description' content='<?=$page->get_description()?>'/>
  47. <meta name='twitter:image' content='<?=$page->get_icon()?>'/>
  48. <meta name='twitter:url' content='<?=$page->get_canonical()?>'/>
  49. <meta name='robots' content='index follow'/>
  50. <script>
  51. /**
  52. * Redirects to the logout action.
  53. */
  54. function logout(){
  55. window.location = '/action/logout/';
  56. }
  57. /**
  58. * Shows an error window.
  59. *
  60. * @param msg Error message
  61. */
  62. function showError(msg){
  63. document.getElementById('error_window').style.display = 'block';
  64. document.getElementById('error_msg').innerHTML = msg;
  65. }
  66. /**
  67. * Closes the error window.
  68. */
  69. function closeError(){
  70. document.getElementById('error_window').style.display = 'none';
  71. document.getElementById('error_msg').innerHTML = ' ';
  72. }
  73. /**
  74. * Shows the mail change form.
  75. */
  76. function changeMail(){
  77. document.getElementById('static_mail').style.display = 'none';
  78. document.getElementById('change_mail').style.display = 'none';
  79. document.getElementById('edit_mail').style.display = 'block';
  80. document.getElementById('save_mail').style.display = 'block';
  81. }
  82. /**
  83. * Saves an email change.
  84. *
  85. * Validates the new email format and makes an AJAX request. If
  86. * succesfull, hides the email change form.
  87. */
  88. function saveMail(){
  89. var http = new XMLHttpRequest();
  90. var mail = document.getElementById('edit_mail').value;
  91. if (mail.length < 1){
  92. showError('Please enter a new email.');
  93. return;
  94. }
  95. if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(mail) == false){
  96. showError('Invalid email');
  97. return;
  98. }
  99. http.open('POST', '/action/edit_profile', true);
  100. http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  101. http.onreadystatechange = function(){
  102. if (this.readyState == 4){
  103. if (this.status == 200 || this.status == 204){
  104. document.getElementById('static_mail').innerHTML = mail;
  105. document.getElementById('static_mail').style.display = 'block';
  106. document.getElementById('change_mail').style.display = 'block';
  107. document.getElementById('edit_mail').style.display = 'none';
  108. document.getElementById('save_mail').style.display = 'none';
  109. }
  110. else{
  111. showError('An error ocurred: ' + this.responseText + ' (' + this.status + ').');
  112. }
  113. }
  114. }
  115. http.send('user=<?=get_context()->get_user()->get_id()?>&mail=' + mail);
  116. }
  117. /**
  118. * Shows the password change form.
  119. */
  120. function changePass(){
  121. document.getElementById('static_pass').style.display = 'none';
  122. document.getElementById('change_pass').style.display = 'none';
  123. document.getElementById('edit_pass_current').value = '';
  124. document.getElementById('edit_pass_current').value = '';
  125. document.getElementById('edit_pass_new').value = '';
  126. document.getElementById('edit_pass_repeat').style.display = 'block';
  127. document.getElementById('edit_pass_new').style.display = 'block';
  128. document.getElementById('edit_pass_repeat').style.display = 'block';
  129. document.getElementById('save_pass').style.display = 'block';
  130. }
  131. /**
  132. * Saves a password change.
  133. *
  134. * Validates the new password and makes an AJAX request. If
  135. * succesfull, hides the password change form.
  136. */
  137. function savePass(){
  138. var http = new XMLHttpRequest();
  139. var pass = document.getElementById('edit_pass_new').value;
  140. var currentPass = document.getElementById('edit_pass_current').value;
  141. var repeatPass = document.getElementById('edit_pass_repeat').value;
  142. if (pass.length < 1){
  143. showError('Please enter a new password.');
  144. return;
  145. }
  146. if (mail.length < 6){
  147. showError('Minimum password length is 6 characters.');
  148. return;
  149. }
  150. if (currentPass.length < 1){
  151. showError('Please enter your current password.');
  152. return;
  153. }
  154. if (pass != repeatPass){
  155. showError('Entered passwords do not match.');
  156. return;
  157. }
  158. http.open('POST', '/action/edit_profile', true);
  159. http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  160. http.onreadystatechange = function(){
  161. if (this.readyState == 4){
  162. if (this.status == 200 || this.status == 204){
  163. document.getElementById('static_pass').style.display = 'block';
  164. document.getElementById('change_pass').style.display = 'block';
  165. document.getElementById('edit_pass_current').style.display = 'none';
  166. document.getElementById('edit_pass_new').style.display = 'none';
  167. document.getElementById('edit_pass_repeat').style.display = 'none';
  168. document.getElementById('save_pass').style.display = 'none';
  169. }
  170. else{
  171. showError('An error ocurred: ' + this.responseText + ' (' + this.status + ').');
  172. }
  173. }
  174. }
  175. http.send('user=<?=get_context()->get_user()->get_id()?>&pass=' + pass + '&currentPass=' + currentPass);
  176. }
  177. /**
  178. * Generates a new random API key.
  179. *
  180. * Makes a request. On success, updates the API in the UI.
  181. */
  182. function regenerateApi(){
  183. var http = new XMLHttpRequest();
  184. http.open('POST', '/action/edit_profile', true);
  185. http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  186. http.onreadystatechange = function(){
  187. if (this.readyState == 4){
  188. if (this.status == 200 || this.status == 204){
  189. document.getElementById('api_key').innerHTML = this.responseText;
  190. }
  191. else{
  192. showError('An error ocurred: ' + this.responseText + ' (' + this.status + ').');
  193. }
  194. }
  195. }
  196. http.send('user=<?=get_context()->get_user()->get_id()?>&api=1');
  197. }
  198. </script>
  199. </head>
  200. <body>
  201. <?php
  202. include __DIR__ . "/inc/header.php";
  203. ?>
  204. <aside>
  205. <h2>
  206. <?=get_context()->get_user()->get_name()?>
  207. </h2>
  208. <p>
  209. Edit your profile settings
  210. </p>
  211. </aside>
  212. <main>
  213. <section class='content'>
  214. <h2>
  215. <?=get_context()->get_user()->get_name()?>
  216. </h2>
  217. <article>
  218. <table id='profile'>
  219. <tr>
  220. <td class='title'>
  221. Username:
  222. </td>
  223. <td class='value'>
  224. <span>
  225. <?=get_context()->get_user()->get_name()?>
  226. </span>
  227. </td>
  228. <td class='action'>
  229. <input onclick='logout();' type='button' value='Logout'/>
  230. </td>
  231. </tr>
  232. <tr>
  233. <td class='title'>
  234. eMail:
  235. </td>
  236. <td class='value'>
  237. <span id='static_mail'>
  238. <?=get_context()->get_user()->get_mail()?>
  239. </span>
  240. <input id='edit_mail' type='text' value='<?=get_context()->get_user()->get_mail()?>'/>
  241. </td>
  242. <td class='action'>
  243. <input id='change_mail' onclick='changeMail();' type='button' value='Change'/>
  244. <input id='save_mail' onclick='saveMail();' type='button' value='Save'/>
  245. </td>
  246. </tr>
  247. <tr>
  248. <td class='title'>
  249. API key:
  250. </td>
  251. <td class='value'>
  252. <span id='api_key'>
  253. <?=get_context()->get_user()->get_api_key()?>
  254. </span>
  255. </td>
  256. <td class='action'>
  257. <input id='regenerate_api' onclick='regenerateApi();' type='button' value='Regenerate'/>
  258. </td>
  259. </tr>
  260. <tr>
  261. <td class='title'>
  262. Password:
  263. </td>
  264. <td class='value'>
  265. <span id='static_pass'>
  266. ********
  267. </span>
  268. <input id='edit_pass_current' type='password' placeholder='Currrent password'/>
  269. <input id='edit_pass_new' type='password' placeholder='New password'/>
  270. <input id='edit_pass_repeat' type='password' placeholder='Repeat password'/>
  271. </td>
  272. <td class='action'>
  273. <input id='change_pass' onclick='changePass();' type='button' value='Change'/>
  274. <input id='save_pass' onclick='savePass();' type='button' value='Save'/>
  275. </td>
  276. </tr>
  277. <tr>
  278. <td class='title'>
  279. Visibility:
  280. </td>
  281. <td id='visibility'>
  282. <input type='checkbox' name='visible' onChange='toggleVisibility(this.value);'/>
  283. <label for='filter_defeat'>Public profile</label>
  284. <div class='help_tooltip'>
  285. <p>
  286. When checked, other users can view you game data. This includes:
  287. <span>Units</span>
  288. <span>Teams</span>
  289. <span>Runes, artifacts and enchantments</span>
  290. <span>Your guild name</span>
  291. <span>Records</span>
  292. <span>Building levels</span>
  293. <span>Guild name</span>
  294. This data will never be shown to other users:
  295. <span>Personal data (email, password...)</span>
  296. <span>Run logs</span>
  297. <span>Statistics</span>
  298. <span>Guild member list</span>
  299. <span>Inventory</span>
  300. <span>Building levels</span>
  301. <span>Guild name</span>
  302. </p>
  303. </div>
  304. </td>
  305. </tr>
  306. </table>
  307. </article>
  308. </section>
  309. </main>
  310. <div id='error_window'>
  311. <section class='content'>
  312. <h2>
  313. <span>
  314. Error
  315. </span>
  316. </h2>
  317. <article>
  318. <p id='error_msg'>
  319. </p>
  320. <input type='button' value='Close' onclick='closeError();'/>
  321. </article>
  322. </section>
  323. </div>
  324. <?php
  325. include __DIR__ . "/inc/footer.php";
  326. ?>
  327. </body>
  328. </html>