admin_prefs.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. <?php
  2. /*
  3. * e107 website system
  4. *
  5. * Copyright (C) 2008-2016 e107 Inc (e107.org)
  6. * Released under the terms and conditions of the
  7. * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
  8. *
  9. * TimeKeeper admin area.
  10. *
  11. * Changes from the current repo version:
  12. * - the "Pending" screen pointed at a table called `Pending` (it doesn't
  13. * exist: the table is timekeeperPending) and its fields were copied from
  14. * the Questions screen, so none matched; now uses the real table/columns
  15. * - new "Preferences" page with a `stats_key` setting. This is the shared
  16. * secret that tk_stats_page.php and timekeeper.php?mode=short check
  17. * (?key=...), so it can be set from the admin area instead of a script
  18. * - pluginName is the plugin folder name in lower case ('timekeeper'); the
  19. * prefs are stored/read under that name (getPlugPref('timekeeper', ...))
  20. * - "Spelling Score" page (customPage): user and subject are escaped when
  21. * printed and in SQL, `e107.e107_tkReport` -> #tkReport, the three nested
  22. * query loops are one GROUP BY query per user, and "next word" no longer
  23. * prints blanks (or warns) when every word already has a usage
  24. * - removed the leftover rss_url*() methods copied from the RSS plugin
  25. */
  26. require_once("../../class2.php");
  27. if (!getperms("P") || !e107::isInstalled('timekeeper')) {
  28. e107::redirect('admin');
  29. exit;
  30. }
  31. // Maybe later i'll setup languages
  32. //e107::includeLan(e_PLUGIN."timekeeper/languages/".e_LANGUAGE."_admin_timekeeper_menu.php");
  33. class timekeeper_admin extends e_admin_dispatcher {
  34. protected $modes = array(
  35. 'main' => array(
  36. 'controller' => 'plugin_tk_admin_ui',
  37. 'path' => null,
  38. 'ui' => 'plugin_tk_admin_form_ui',
  39. 'uipath' => null
  40. ),
  41. 'score' => array(
  42. 'controller' => 'tk_Score_ui',
  43. 'path' => null,
  44. 'ui' => 'tk_Score_form_ui',
  45. 'uipath' => null
  46. ),
  47. 'pending' => array(
  48. 'controller' => 'tk_Pending_ui',
  49. 'path' => null,
  50. 'ui' => 'tk_Pending_form_ui',
  51. 'uipath' => null
  52. ),
  53. 'report' => array(
  54. 'controller' => 'tk_Report_ui',
  55. 'path' => null,
  56. 'ui' => 'tk_Report_form_ui',
  57. 'uipath' => null
  58. ),
  59. 'reportold' => array(
  60. 'controller' => 'tk_Reportold_ui',
  61. 'path' => null,
  62. 'ui' => 'tk_Reportold_form_ui',
  63. 'uipath' => null
  64. ),
  65. 'wordlist' => array(
  66. 'controller' => 'tk_Wordlist_ui',
  67. 'path' => null,
  68. 'ui' => 'tk_Wordlist_form_ui',
  69. 'uipath' => null
  70. ),
  71. 'geography' => array(
  72. 'controller' => 'tk_geography_ui',
  73. 'path' => null,
  74. 'ui' => 'tk_geography_form_ui',
  75. 'uipath' => null
  76. ),
  77. );
  78. protected $adminMenu = array(
  79. 'main/list' => array('caption' => 'List Questions', 'perm' => '0'),
  80. 'main/create' => array('caption' => LAN_CREATE, 'perm' => '0'),
  81. 'main/prefs' => array('caption' => LAN_PREFS, 'perm' => '0'),
  82. 'other0' => array('divider' => true),
  83. //'subjects/list' => array('caption'=> 'List Subjects', 'perm' => '0'),
  84. //'subjects/create' => array('caption'=> 'Add Subjects', 'perm' => '0'),
  85. //'other1' => array('divider' => true),
  86. 'Score/list' => array('caption' => 'List Score', 'perm' => '0'),
  87. 'other2' => array('divider' => true),
  88. 'Pending/list' => array('caption' => 'List Pending', 'perm' => '0'),
  89. 'other3' => array('divider' => true),
  90. 'Report/list' => array('caption' => 'List Report', 'perm' => '0'),
  91. 'Reportold/list' => array('caption' => 'List Report (Old)', 'perm' => '0'),
  92. 'other4' => array('divider' => true),
  93. 'Wordlist/list' => array('caption' => 'Spelling Words', 'perm' => '0'),
  94. 'Wordlist/create' => array('caption' => 'Add Words', 'perm' => '0'),
  95. 'Wordlist/custom' => array('caption' => 'Spelling Score', 'perm' => '0'),
  96. 'other5' => array('divider' => true),
  97. 'Geography/list' => array('caption' => 'Geography', 'perm' => '0'),
  98. );
  99. protected $adminMenuAliases = array(
  100. 'main/edit' => 'main/list'
  101. );
  102. protected $menuTitle = 'TimeKeeper';
  103. }
  104. /*
  105. =========================================================================
  106. ===== Questions table interface (and plugin preferences)
  107. =========================================================================
  108. */
  109. class plugin_tk_admin_ui extends e_admin_ui {
  110. protected $pluginTitle = 'TimeKeeper';
  111. protected $pluginName = 'timekeeper';
  112. protected $table = 'timekeeperQuestions';
  113. protected $pid = 'timekeeper_id';
  114. protected $perPage = 10;
  115. protected $fields = array(
  116. 'checkboxes' => array('title' => '', 'type' => null, 'data' => false, 'width' => '5%', 'thclass' => 'center', 'forced' => '1', 'class' => 'center', 'toggle' => 'e-multiselect',),
  117. 'timekeeper_id' => array('title' => LAN_ID, 'data' => 'int', 'width' => '5%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  118. 'timekeeper_questiondescription' => array('title' => LAN_TITLE, 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  119. 'timekeeper_question' => array('title' => "Question", 'type' => 'text', 'data' => 'str', 'readonly' => 1, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  120. 'timekeeper_answers' => array('title' => "Answers", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  121. 'timekeeper_subject' => array('title' => "Subject", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  122. 'timekeeper_addeddatestamp' => array('title' => LAN_DATESTAMP, 'type' => 'datestamp', 'data' => 'int', 'readonly' => true, 'width' => 'auto', 'filter' => true, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  123. 'timekeeper_yearlevel' => array('title' => "Year Level", 'type' => 'dropdown', 'data' => 'int', 'inline' => true, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => array('optArray' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)), 'class' => 'left', 'thclass' => 'left',),
  124. 'timekeeper_correctanswer' => array('title' => "Correct Answer", 'type' => 'number', 'data' => 'int', 'inline' => true, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  125. 'options' => array('title' => LAN_OPTIONS, 'type' => null, 'data' => '', 'width' => '10%', 'thclass' => 'center last', 'class' => 'center last', 'forced' => '1',),
  126. );
  127. protected $fieldpref = array('checkboxes', 'timekeeper_questiondescription', 'timekeeper_question', 'timekeeper_answers', 'timekeeper_correctanswer', 'timekeeper_yearlevel', 'options');
  128. // Plugin preferences (Preferences page). Read elsewhere with
  129. // e107::getPlugPref('timekeeper', 'stats_key', '').
  130. protected $prefs = array(
  131. 'stats_key' => array(
  132. 'title' => 'Stats / summary key',
  133. 'type' => 'text',
  134. 'data' => 'str',
  135. 'help' => 'Shared secret for tk_stats_page.php and timekeeper.php?mode=short: add &key=<this value> to the URL. Leave empty for no key (tk_stats_page.php is then open to anyone).',
  136. 'writeParms' => array('size' => 'xxlarge'),
  137. ),
  138. );
  139. }
  140. class plugin_tk_admin_form_ui extends e_admin_form_ui {
  141. }
  142. /*
  143. =========================================================================
  144. ===== Score table interface
  145. =========================================================================
  146. */
  147. class tk_Score_ui extends e_admin_ui {
  148. protected $pluginTitle = 'TimeKeeper';
  149. protected $pluginName = 'timekeeper';
  150. protected $table = 'timekeeperScore';
  151. protected $pid = 'timekeeper_id';
  152. protected $perPage = 10;
  153. protected $fields = array(
  154. 'checkboxes' => array('title' => '', 'type' => null, 'data' => false, 'width' => '5%', 'thclass' => 'center', 'forced' => '1', 'class' => 'center', 'toggle' => 'e-multiselect',),
  155. 'timekeeper_id' => array('title' => LAN_ID, 'data' => 'int', 'width' => '5%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  156. 'timekeeper_username' => array('title' => "User Name", 'type' => 'text', 'data' => 'str', 'readonly' => 1, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  157. 'timekeeper_lifetimequestions' => array('title' => "life time Question", 'type' => 'text', 'data' => 'str', 'readonly' => 1, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  158. 'timekeeper_lifetimecorrect' => array('title' => "life time correct", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  159. 'timekeeper_minutes' => array('title' => "minutes", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  160. 'timekeeper_lastquestiondatestamp' => array('title' => LAN_DATESTAMP, 'type' => 'datestamp', 'data' => 'int', 'readonly' => true, 'width' => 'auto', 'filter' => true, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  161. 'timekeeper_yearlevel' => array('title' => "Year Level", 'type' => 'dropdown', 'data' => 'int', 'inline' => true, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => array('optArray' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)), 'class' => 'left', 'thclass' => 'left',),
  162. 'options' => array('title' => LAN_OPTIONS, 'type' => null, 'data' => '', 'width' => '10%', 'thclass' => 'center last', 'class' => 'center last', 'forced' => '1',),
  163. );
  164. protected $fieldpref = array('checkboxes', 'timekeeper_username', 'timekeeper_lifetimequestions', 'timekeeper_lifetimecorrect', 'timekeeper_minutes', 'options');
  165. }
  166. class tk_Score_form_ui extends e_admin_form_ui {
  167. }
  168. /*
  169. =========================================================================
  170. ===== Pending table interface
  171. =========================================================================
  172. */
  173. class tk_Pending_ui extends e_admin_ui {
  174. protected $pluginTitle = 'TimeKeeper';
  175. protected $pluginName = 'timekeeper';
  176. protected $table = 'timekeeperPending';
  177. protected $pid = 'timekeeper_id';
  178. protected $perPage = 10;
  179. protected $fields = array(
  180. 'checkboxes' => array('title' => '', 'type' => null, 'data' => false, 'width' => '5%', 'thclass' => 'center', 'forced' => '1', 'class' => 'center', 'toggle' => 'e-multiselect',),
  181. 'timekeeper_id' => array('title' => LAN_ID, 'data' => 'int', 'width' => '5%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  182. 'timekeeper_username' => array('title' => "User Name", 'type' => 'text', 'data' => 'str', 'readonly' => 1, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  183. 'timekeeper_question' => array('title' => "Question", 'type' => 'number', 'data' => 'int', 'readonly' => 1, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  184. 'timekeeper_answereddatestamp' => array('title' => LAN_DATESTAMP, 'type' => 'datestamp', 'data' => 'int', 'readonly' => true, 'width' => 'auto', 'filter' => true, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  185. 'timekeeper_answer' => array('title' => "Answer", 'type' => 'textarea', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  186. 'options' => array('title' => LAN_OPTIONS, 'type' => null, 'data' => '', 'width' => '10%', 'thclass' => 'center last', 'class' => 'center last', 'forced' => '1',),
  187. );
  188. protected $fieldpref = array('checkboxes', 'timekeeper_username', 'timekeeper_question', 'timekeeper_answereddatestamp', 'timekeeper_answer', 'options');
  189. }
  190. class tk_Pending_form_ui extends e_admin_form_ui {
  191. }
  192. /*
  193. =========================================================================
  194. ===== Report table interface
  195. =========================================================================
  196. */
  197. class tk_Report_ui extends e_admin_ui {
  198. protected $pluginTitle = 'TimeKeeper';
  199. protected $pluginName = 'timekeeper';
  200. protected $table = 'tkReport';
  201. protected $pid = 'id';
  202. protected $perPage = 10;
  203. protected $fields = array(
  204. 'checkboxes' => array('title' => '', 'type' => null, 'data' => false, 'width' => '5%', 'thclass' => 'center', 'forced' => '1', 'class' => 'center', 'toggle' => 'e-multiselect',),
  205. 'id' => array('title' => LAN_ID, 'data' => 'int', 'width' => '5%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  206. 'username' => array('title' => "User Name", 'type' => 'text', 'data' => 'str', 'readonly' => 1, 'width' => 'auto', 'filter' => true, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  207. 'question' => array('title' => "Question", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  208. 'userAnswer' => array('title' => "User Answer", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  209. 'answer' => array('title' => "Correct Answer", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  210. 'subject' => array('title' => "Subject", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  211. 'answereddatestamp' => array('title' => LAN_DATESTAMP, 'type' => 'datestamp', 'data' => 'int', 'readonly' => true, 'width' => 'auto', 'filter' => true, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  212. 'correct' => array('title' => "Correct", 'type' => 'bool', 'data' => 'int', 'inline' => true, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  213. 'options' => array('title' => LAN_OPTIONS, 'type' => null, 'data' => '', 'width' => '10%', 'thclass' => 'center last', 'class' => 'center last', 'forced' => '1',),
  214. );
  215. protected $fieldpref = array('checkboxes', 'username', 'question', 'userAnswer', 'answer', 'options');
  216. }
  217. class tk_Report_form_ui extends e_admin_form_ui {
  218. }
  219. class tk_Reportold_ui extends e_admin_ui {
  220. protected $pluginTitle = 'TimeKeeper';
  221. protected $pluginName = 'timekeeper';
  222. protected $table = 'timekeeperReport';
  223. protected $pid = 'timekeeper_id';
  224. protected $perPage = 10;
  225. protected $fields = array(
  226. 'checkboxes' => array('title' => '', 'type' => null, 'data' => false, 'width' => '5%', 'thclass' => 'center', 'forced' => '1', 'class' => 'center', 'toggle' => 'e-multiselect',),
  227. 'timekeeper_id' => array('title' => LAN_ID, 'data' => 'int', 'width' => '5%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  228. 'timekeeper_username' => array('title' => "User Name", 'type' => 'text', 'data' => 'str', 'readonly' => 1, 'width' => 'auto', 'filter' => true, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  229. 'timekeeper_question' => array('title' => "Question", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  230. 'timekeeper_userAnswer' => array('title' => "User Answer", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  231. 'timekeeper_answer' => array('title' => "Correct Answer", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  232. 'timekeeper_subject' => array('title' => "Subject", 'type' => 'text', 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  233. 'timekeeper_answereddatestamp' => array('title' => LAN_DATESTAMP, 'type' => 'datestamp', 'data' => 'int', 'readonly' => true, 'width' => 'auto', 'filter' => true, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  234. 'timekeeper_yearLevel' => array('title' => "Year Level", 'type' => 'number', 'data' => 'int', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  235. 'timekeeper_correct' => array('title' => "Correct", 'type' => 'bool', 'data' => 'int', 'inline' => true, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  236. 'options' => array('title' => LAN_OPTIONS, 'type' => null, 'data' => '', 'width' => '10%', 'thclass' => 'center last', 'class' => 'center last', 'forced' => '1',),
  237. );
  238. protected $fieldpref = array('checkboxes', 'timekeeper_username', 'timekeeper_question', 'timekeeper_userAnswer', 'timekeeper_answer', 'timekeeper_yearLevel', 'options');
  239. }
  240. class tk_Reportold_form_ui extends e_admin_form_ui {
  241. }
  242. /*
  243. =========================================================================
  244. ===== Wordlist table interface
  245. =========================================================================
  246. */
  247. class tk_Wordlist_ui extends e_admin_ui {
  248. protected $pluginTitle = 'TimeKeeper';
  249. protected $pluginName = 'timekeeper';
  250. protected $table = 'tk_wordList';
  251. protected $pid = 'indexNo';
  252. protected $perPage = 10;
  253. protected $fields = array(
  254. 'checkboxes' => array('title' => '', 'type' => null, 'data' => false, 'width' => '5%', 'thclass' => 'center', 'forced' => '1', 'class' => 'center', 'toggle' => 'e-multiselect',),
  255. 'indexNo' => array('title' => LAN_ID, 'data' => 'int', 'width' => '5%', 'readonly' => 1, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  256. 'word' => array('title' => "Word", 'type' => 'text', 'data' => 'str', 'readonly' => 1, 'width' => '10%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  257. 'usage' => array('title' => "Word Usage", 'type' => 'textarea', 'data' => 'str', 'width' => '65%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  258. 'year' => array('title' => "Year Level", 'type' => 'number', 'data' => 'int', 'width' => '5%', 'help' => '', 'readParms' => '', 'writeParms' => ['default' => 1, 'min' => 1, 'max' => 13], 'class' => 'left', 'thclass' => 'left',),
  259. 'options' => array('title' => LAN_OPTIONS, 'type' => null, 'data' => '', 'width' => '10%', 'thclass' => 'center last', 'class' => 'center last', 'forced' => '1',),
  260. );
  261. protected $fieldpref = array('checkboxes', 'indexNo', 'word', 'usage', 'year', 'options');
  262. private function esc($value) {
  263. return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8');
  264. }
  265. /**
  266. * "Spelling Score" page: last month's score per user and subject, a
  267. * difficulty figure per user, and how many words still need a usage.
  268. */
  269. public function customPage() {
  270. $sql = e107::getDb();
  271. $text = '<table style="width:600px;"><tr><td style="width:25%;">User</td><td style="width:25%;">Subject</td><td style="width:24%;">Percentage</td><td style="width:25%;">Questions last month</td></tr>';
  272. $users = [];
  273. $sql->gen("SELECT DISTINCT username FROM `#tkReport` WHERE `answereddatestamp` > UNIX_TIMESTAMP(NOW() - INTERVAL 1 MONTH)");
  274. while ($row = $sql->fetch()) {
  275. $users[] = $row['username'];
  276. }
  277. foreach ($users as $user) {
  278. $u = $sql->escape($user);
  279. // Score per subject, last month.
  280. $sql->gen("SELECT `subject`, CAST((SUM(correct) / COUNT(id) * 100) AS DECIMAL(5,2)) AS percent, COUNT(id) AS `count`
  281. FROM `#tkReport`
  282. WHERE `answereddatestamp` > UNIX_TIMESTAMP(NOW() - INTERVAL 1 MONTH) AND `username` = '{$u}'
  283. GROUP BY `subject` ORDER BY `subject`");
  284. while ($row = $sql->fetch()) {
  285. $text .= '<tr><td>' . $this->esc($user) . '</td><td>' . $this->esc($row['subject']) . '</td><td>' . $this->esc($row['percent']) . '</td><td>' . (int) $row['count'] . '</td></tr>';
  286. }
  287. // Difficulty as the game computes it: all-time question count x last month's overall percent.
  288. $totalQuestionCount = (int) $sql->count('tkReport', '(id)', "username = '{$u}'");
  289. $sql->gen("SELECT CAST((SUM(correct)/COUNT(id)*100) AS DECIMAL(5,2)) AS percent
  290. FROM `#tkReport` WHERE username = '{$u}'
  291. AND answereddatestamp >= UNIX_TIMESTAMP(CURRENT_DATE() - INTERVAL 1 MONTH)
  292. AND answereddatestamp <= UNIX_TIMESTAMP(CURRENT_DATE() + INTERVAL 1 DAY)");
  293. $row = $sql->fetch();
  294. $percent = (is_array($row) && $row['percent'] !== null) ? (float) $row['percent'] : 0;
  295. $text .= '<tr><td colspan=2>Difficulty</td><td colspan=2>' . ($totalQuestionCount * $percent) . '</td></tr>';
  296. }
  297. $text .= '</table><br/><br/>';
  298. $missing = (int) $sql->retrieve("SELECT COUNT(*) FROM `#tk_wordList` WHERE `usage` = '' OR `usage` IS NULL");
  299. $text .= $missing . ' words need a usage entered.<br/>';
  300. $nextWord = $sql->retrieve("SELECT `indexNo`, `word` FROM `#tk_wordList` WHERE `usage` = '' OR `usage` IS NULL ORDER BY `indexNo` LIMIT 1");
  301. if (is_array($nextWord)) {
  302. $text .= 'The next word to be entered is "' . $this->esc($nextWord['word']) . '" at position ' . (int) $nextWord['indexNo'] . '.';
  303. } else {
  304. $text .= 'Every word has a usage entered.';
  305. }
  306. $ns = e107::getRender();
  307. $ns->tablerender("Scores", $text);
  308. }
  309. }
  310. class tk_Wordlist_form_ui extends e_admin_form_ui {
  311. }
  312. class tk_geography_ui extends e_admin_ui {
  313. protected $pluginTitle = 'TimeKeeper';
  314. protected $pluginName = 'timekeeper';
  315. protected $table = 'tk_countries';
  316. protected $pid = 'id';
  317. protected $perPage = 10;
  318. protected $fields = array(
  319. 'checkboxes' => array('title' => '', 'type' => null, 'data' => false, 'width' => '5%', 'thclass' => 'center', 'forced' => '1', 'class' => 'center', 'toggle' => 'e-multiselect',),
  320. 'id' => array('title' => LAN_ID, 'data' => 'int', 'width' => '5%', 'readonly' => 1, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  321. 'country' => array('title' => "Country", 'type' => 'text', 'data' => 'str', 'readonly' => 1, 'width' => '10%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  322. 'currency' => array('title' => "Currency", 'type' => 'text', 'data' => 'str', 'width' => '10%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  323. 'capital' => array('title' => "Capital", 'type' => 'text', 'data' => 'str', 'width' => '10%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  324. 'isoCode' => array('title' => "isoCode", 'type' => 'text', 'data' => 'str', 'width' => '5%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  325. 'difficulty' => array('title' => "Difficulty", 'type' => 'number', 'data' => 'int', 'inline' => true, 'width' => '5%', 'help' => '', 'readParms' => '', 'writeParms' => ['default' => 10, 'min' => 1, 'max' => 10], 'class' => 'left', 'thclass' => 'left',),
  326. 'culture' => array('title' => "Culture", 'type' => 'textarea', 'data' => 'str', 'width' => '20%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left',),
  327. 'continent' => array('title' => "Continent", 'type' => 'dropdown', 'data' => 'str', 'inline' => true, 'width' => '10%', 'help' => '', 'readParms' => '', 'writeParms' => ['optArray' => ['Africa'=>'Africa', 'Asia'=>'Asia', 'Europe'=>'Europe', 'North America'=>'North America', 'South America'=>'South America', 'Oceania'=>'Oceania']], 'class' => 'left', 'thclass' => 'left',),
  328. 'map_coords' => array('title' => "Map Coords", 'type' => 'text', 'data' => 'str', 'width' => '10%', 'help' => '', 'readParms' => '', 'writeParms' => ['default' => '{}'], 'class' => 'left', 'thclass' => 'left',),
  329. 'options' => array('title' => LAN_OPTIONS, 'type' => null, 'data' => '', 'width' => '10%', 'thclass' => 'center last', 'class' => 'center last', 'forced' => '1',),
  330. );
  331. protected $fieldpref = array('checkboxes', 'id', 'country', 'isoCode', 'difficulty', 'options');
  332. }
  333. class tk_geography_form_ui extends e_admin_form_ui {
  334. }
  335. new timekeeper_admin();
  336. require_once(e_ADMIN . "auth.php");
  337. e107::getAdminUI()->runPage();
  338. require_once(e_ADMIN . "footer.php");
  339. exit;