PreHeaderFunctions.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. <?php
  2. /*
  3. * To change this license header, choose License Headers in Project Properties.
  4. * To change this template file, choose Tools | Templates
  5. * and open the template in the editor.
  6. */
  7. /**
  8. * Description of ExcelFunctions
  9. *
  10. * @author gregory
  11. */
  12. class ExcelFunctions {
  13. public function GeneratePdf() {
  14. //require_once(e_PLUGIN.'pdf/e107pdf.php'); //require the e107pdf class
  15. //$pdf = new e107PDF();// e_IMAGE.'admin_images/true_32.png' e_IMAGE.'admin_images/false_32.png'
  16. $user = filter_input(INPUT_GET, 'user');
  17. $whereDate = $this->whereDate();
  18. if ($user == "") {
  19. return;
  20. }
  21. $text = '<h1>TimeKeeper Report</h1>';
  22. $sql = e107::getDb();
  23. // $text .= $this->coverPage($sql,$user,$whereDate);
  24. $text .= $this->questionsTable($sql, $user, $whereDate);
  25. $text .= "\nMemory use: " . (memory_get_peak_usage(true) / 1024 / 1024) . " MiB.\nGeneration time " . (microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]) . ' seconds.';
  26. file_put_contents('test.html', $text);
  27. $sql->close();
  28. $stdOut = '';
  29. $output = filter_input(INPUT_GET, 'output');
  30. if ($output == 'html') {
  31. echo $text;
  32. exit;
  33. } elseif ($output == 'pdf') {
  34. if (!preg_match('/^[A-Za-z0-9_-]{1,50}$/', $user)) {
  35. return;
  36. }
  37. $html = tempnam(sys_get_temp_dir(), 'tk') . '.html';
  38. $pdf = tempnam(sys_get_temp_dir(), 'tk') . '.pdf';
  39. file_put_contents($html, $text);
  40. exec('wkhtmltopdf ' . escapeshellarg($html) . ' ' . escapeshellarg($pdf));
  41. }
  42. $filename = "$user.pdf";
  43. // Header content type
  44. header("Content-type: application/pdf");
  45. header("Content-Length: " . filesize($filename));
  46. // Send the file to the browser.
  47. readfile($filename);
  48. exit;
  49. }
  50. private function coverPage($sql, $user, $whereDate) {
  51. if (false) {
  52. $sql->gen("SELECT `subject`,
  53. ANY_VALUE(`percent`) as percent, ANY_VALUE(`quantity`) as quantity
  54. FROM e107.`e107_tkStats` WHERE `username` = '$user' GROUP BY (`subject`);");
  55. $text = '<table border="1" cellspacing="3" cellpadding="2">'
  56. . '<tr><td style="text-align:left">Subject</td><td>Score</td><td>Questions Remaining</td></tr>';
  57. while ($row = $sql->fetch()) {
  58. $text .= '<tr><td style="text-align:left">' . ucfirst($row['subject']) . '</td><td>' . $row['percent'] . '%</td><td>' . (1000 - $row['quantity']) . '</td></tr>';
  59. }
  60. } else {
  61. $sql->gen("SELECT COUNT(_id) as cntr, CAST((SUM(correct)/COUNT(id)*100) as DECIMAL(5,2)) as percent
  62. FROM e107.`e107_tkReport` WHERE username = '$user'
  63. $whereDate");
  64. while ($row = $sql->fetch()) {
  65. if (filter_input(INPUT_GET, 'range') == "" || filter_input(INPUT_GET, 'range') == "today") {
  66. $text .= '<p>' . $row['cntr'] . ' question(s) have been answered for today with ' . $row['percent'] . '% accuracy.</p>';
  67. } else {
  68. $text .= '<p>' . $row['cntr'] . ' question(s) have been answered for this ' . filter_input(INPUT_GET, 'range') . ' with ' . $row['percent'] . '% accuracy.</p>';
  69. }
  70. }
  71. }
  72. $text .= '</table>';
  73. return $text;
  74. }
  75. private function questionsTable($sql, $user, $whereDate) {
  76. $sql->gen("SELECT * FROM e107.e107_tkReport WHERE username='$user' $whereDate ORDER BY subject;");
  77. $head = "";
  78. $text = "";
  79. while ($row = $sql->fetch()) {
  80. if ($head == "") {
  81. $head = $row["subject"];
  82. $text .= '<h3>' . ucfirst($head) . '</h3>'
  83. . '<table border="1" cellspacing="3" cellpadding="2">'
  84. . '<tr>'
  85. . '<td width="1295">Question</td>'
  86. . '<td width="75">User Answer</td>'
  87. . '<td width="75">Correct Answer</td>'
  88. . '<td width="25"></td>'
  89. . '</tr>';
  90. } elseif ($head != $row["subject"]) {
  91. $head = $row["subject"];
  92. $text .= '</table><h3>' . ucfirst($head) . '</h3><table border="1" cellspacing="3" cellpadding="2"><tr><td width="1295">Question</td><td width="75">User Answer</td><td width="75">Correct Answer</td><td width="25"></td></tr>';
  93. }
  94. $text .= "<tr><td>" . $row["question"] . '</td><td>' . $row["userAnswer"] . '</td><td>' . $row["answer"] . '</td><td>' . $this->correctOrNot($row["correct"]) . '</td></tr>';
  95. }
  96. $text .= '</table>';
  97. return $text;
  98. }
  99. private function whereDate() {
  100. $returnRange = filter_input(INPUT_GET, 'range');
  101. $unixTimeTodayEnd = mktime(23, 59, 59, date('n'), date('j'));
  102. $returnValues = ['today' => ['start' => strtotime('- 24 hours', $unixTimeTodayEnd), 'end' => $unixTimeTodayEnd]
  103. , 'yesterday' => ['start' => strtotime('- 48 hours', $unixTimeTodayEnd), 'end' => strtotime('- 24 hours', $unixTimeTodayEnd)]
  104. , 'pastWeek' => ['start' => strtotime('- 7 days', $unixTimeTodayEnd), 'end' => $unixTimeTodayEnd]
  105. , 'pastMonth' => ['start' => strtotime('- 1 month', $unixTimeTodayEnd), 'end' => $unixTimeTodayEnd]
  106. , 'pastQuarter' => ['start' => strtotime('- 3 month', $unixTimeTodayEnd), 'end' => $unixTimeTodayEnd]
  107. , 'pastYear' => ['start' => strtotime('- 1 year', $unixTimeTodayEnd), 'end' => $unixTimeTodayEnd]
  108. ];
  109. if (!isset($returnValues[$returnRange])) {
  110. $returnRange = 'today';
  111. }
  112. return "AND answereddatestamp>='" . $returnValues[$returnRange]['start'] . "' AND answereddatestamp<='" . $returnValues[$returnRange]['end'] . "'";
  113. }
  114. private function correctOrNot($state) {
  115. if ($state) {
  116. return '<img src="' . e_IMAGE . 'admin_images/true_16.png"/>';
  117. } else {
  118. return '<img src="' . e_IMAGE . 'admin_images/false_16.png"/>';
  119. }
  120. }
  121. public function GenerateExcel() {
  122. require_once('phar://lib/PHPExcel.phar/PHPExcel.php');
  123. $objPHPExcel = new PHPExcel();
  124. $objPHPExcel->getProperties()->setCreator("Gregory J Huxley")->setLastModifiedBy("TimeKeeper");
  125. $this->buildSheet($objPHPExcel);
  126. $this->setHeader();
  127. $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
  128. $objWriter->setPreCalculateFormulas(true);
  129. $objWriter->save('php://output');
  130. exit;
  131. }
  132. private function buildSheet($objPHPExcel) {
  133. $numberOfQuestions = filter_input(INPUT_POST, 'numberOfQuestions');
  134. if (!$numberOfQuestions) {
  135. $numberOfQuestions = 5;
  136. }
  137. $objPHPExcel->getActiveSheet()->setTitle("Questions");
  138. for ($i = 0; $i <= $numberOfQuestions; $i++) {
  139. $counter = 0;
  140. foreach ($this->buildQuestion($i) as $value) {
  141. $objPHPExcel->setActiveSheetIndex(0)->setCellValueByColumnAndRow($counter, $i, $value);
  142. $counter++;
  143. }
  144. }
  145. }
  146. private function buildQuestion($i) {//http://localhost/e107_plugins/timekeeper/timekeeper.php?numberOfQuestions=20&addition=0&addition__switch=0&subtraction=0&multiplication=0&division=0&GetExcel=Generate+Sheet
  147. while (true) {
  148. switch (rand(1, 4)) {
  149. case 1:// addition
  150. $enabledSubject = filter_has_var(INPUT_POST, 'addition__switch');
  151. if ($enabledSubject) {
  152. return $this->addition($i);
  153. }
  154. break;
  155. case 2:// subtraction
  156. $enabledSubject = filter_has_var(INPUT_POST, 'subtraction__switch');
  157. if ($enabledSubject) {
  158. return $this->subtraction($i);
  159. }
  160. break;
  161. case 3:// multiplication
  162. $enabledSubject = filter_has_var(INPUT_POST, 'multiplication__switch');
  163. if ($enabledSubject) {
  164. return $this->multiplication($i);
  165. }
  166. break;
  167. case 4:// division
  168. $enabledSubject = filter_has_var(INPUT_POST, 'division__switch');
  169. if ($enabledSubject) {
  170. return $this->division($i);
  171. }
  172. break;
  173. }
  174. }
  175. }
  176. private function addition($i) {
  177. $question = [rand(1, 1000)];
  178. for ($int = 1; $int <= rand(1, 3); $int++) {
  179. array_push($question, '+');
  180. array_push($question, rand(1, 1000));
  181. }
  182. array_push($question, '=');
  183. array_push($question, $this->checkFormula($i, $question));
  184. return $question;
  185. }
  186. private function subtraction($i) {
  187. $question = [rand(100, 1000)];
  188. for ($int = 1; $int <= rand(1, 2); $int++) {
  189. array_push($question, '-');
  190. array_push($question, rand(1, $question[0] / 2));
  191. }
  192. array_push($question, '=');
  193. array_push($question, $this->checkFormula($i, $question));
  194. return $question;
  195. }
  196. private function multiplication($i) {
  197. $startNumber = [rand(1, 99)];
  198. $question = $startNumber;
  199. for ($int = 1; $int <= rand(1, 1); $int++) {
  200. array_push($question, '*');
  201. array_push($question, rand(1, $startNumber));
  202. }
  203. array_push($question, '=');
  204. array_push($question, $this->checkFormula($i, $question));
  205. return $question;
  206. }
  207. private function division($i) {
  208. $startNumber = rand(1, 50);
  209. $endNumber = rand(1, 5);
  210. $question = [$startNumber * $endNumber];
  211. array_push($question, '/');
  212. array_push($question, $endNumber);
  213. array_push($question, '=');
  214. array_push($question, $this->checkFormula($i, $question));
  215. return $question;
  216. }
  217. private function checkFormula($i, &$question) {
  218. $letters = ['A', 'C', 'E', 'G', 'I'];
  219. for ($int = count($question); $int <= 8; $int++) {
  220. array_push($question, '');
  221. }
  222. $formula = '(';
  223. $counter = 0;
  224. foreach ($question as &$value) {
  225. if ($value == '+' || $value == '-' || $value == '*' || $value == '/') {
  226. $formula .= $value;
  227. } elseif ($value == '=') {
  228. $formula .= ')=' . $letters[$counter] . $i;
  229. break;
  230. } else {
  231. $formula .= $letters[$counter] . $i;
  232. $counter++;
  233. }
  234. }
  235. return '=IF(' . substr(strrchr($formula, "="), 1) . '="","",IF(' . $formula . ',"Correct","Wrong"))'; // =IF(L1="","",IF((A1*C1*E1*H1*J1)=L1,"Correct","Wrong"))
  236. }
  237. private function setHeader() {
  238. // Redirect output to a client’s web browser (Excel2007)
  239. header('Content-Type: application/vnd.ms-excel');
  240. header('Content-Disposition: attachment;filename="Questions.xls"');
  241. header('Cache-Control: max-age=0');
  242. // If you're serving to IE 9, then the following may be needed
  243. header('Cache-Control: max-age=1');
  244. // If you're serving to IE over SSL, then the following may be needed
  245. header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
  246. header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
  247. header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
  248. header('Pragma: public'); // HTTP/1.0
  249. }
  250. }
  251. /**
  252. * Description of Summary
  253. *
  254. * @author gregory
  255. */
  256. class Summary {
  257. public function GenerateSummary() {//base64_encode
  258. $user = filter_input(INPUT_GET, 'user');
  259. $whereDate = $this->whereDate();
  260. if ($user == "") {
  261. return;
  262. }
  263. $sql = e107::getDb();
  264. $text = '<body style="background-color:#31363b;"><div style="font-size:250%;color:#fcfcfc;">';
  265. $text .= $this->coverPage($sql, $user, $whereDate);
  266. //$text .= "\nMemory use: ".(memory_get_peak_usage(true)/1024/1024)." MiB.\nGeneration time " . (microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]).' seconds.';
  267. //print_a($whereDate);
  268. $sql->close();
  269. echo $text . '</div></body>';
  270. //$pdf->makePDF([$text, 'e107site', 'Gregory', 'Timekeeper Report', 'Timekeeper Report', 'Timekeeper Report', e_PLUGIN.'/timekeeper/timekeeper.php']);
  271. exit;
  272. }
  273. private function coverPage($sql, $user, $whereDate) {
  274. if (false) {
  275. $sql->gen("SELECT MAX(`timekeeper_yearLevel`) as timekeeper_yearLevel, `timekeeper_subject`,
  276. ANY_VALUE(`timekeeper_percent`) as timekeeper_percent, ANY_VALUE(`timekeeper_quantity`) as timekeeper_quantity
  277. FROM e107.`e107_timekeeperStats` WHERE `timekeeper_username` = '$user' GROUP BY (`timekeeper_subject`);");
  278. $text = '<table border="1" cellspacing="3" cellpadding="2">'
  279. . '<tr><td style="text-align:left">Year</td><td style="text-align:left">Subject</td><td>Score</td><td>Questions Remaining</td></tr>';
  280. while ($row = $sql->fetch()) {
  281. $text .= '<tr><td>' . $row['timekeeper_yearLevel'] . '</td><td style="text-align:left">' . ucfirst($row['timekeeper_subject']) . '</td><td>' . $row['timekeeper_percent'] . '%</td><td>' . (1000 - $row['timekeeper_quantity']) . '</td></tr>';
  282. }
  283. } else {
  284. $sql->gen("SELECT COUNT(id) as cntr, CAST((SUM(correct)/COUNT(id)*100) as DECIMAL(5,2)) as percent
  285. FROM e107.`e107_tkReport` WHERE username = '$user'
  286. $whereDate");
  287. while ($row = $sql->fetch()) {
  288. if (filter_input(INPUT_GET, 'range') == "" || filter_input(INPUT_GET, 'range') == "today") {
  289. $text .= 'Questions ' . filter_input(INPUT_GET, 'range') . '<br/><br/>' . $row['cntr'] . '<br/>' . $row['percent'] . '% correct.';
  290. } else {
  291. $text .= 'Questions ' . filter_input(INPUT_GET, 'range') . ' ' . $row['cntr'] . '<br/><br/>' . $row['percent'] . '% correct.';
  292. }
  293. }
  294. }
  295. $text .= '</table>';
  296. return $text;
  297. }
  298. private function whereDate() {
  299. $returnRange = filter_input(INPUT_GET, 'range');
  300. $unixTimeTodayEnd = mktime(23, 59, 59, date('n'), date('j'));
  301. $returnValues = ['today' => ['start' => strtotime('- 24 hours', $unixTimeTodayEnd), 'end' => $unixTimeTodayEnd]
  302. , 'yesterday' => ['start' => strtotime('- 48 hours', $unixTimeTodayEnd), 'end' => strtotime('- 24 hours', $unixTimeTodayEnd)]
  303. , 'pastWeek' => ['start' => strtotime('- 7 days', $unixTimeTodayEnd), 'end' => $unixTimeTodayEnd]
  304. , 'pastMonth' => ['start' => strtotime('- 1 month', $unixTimeTodayEnd), 'end' => $unixTimeTodayEnd]
  305. , 'pastQuarter' => ['start' => strtotime('- 3 month', $unixTimeTodayEnd), 'end' => $unixTimeTodayEnd]
  306. , 'pastYear' => ['start' => strtotime('- 1 year', $unixTimeTodayEnd), 'end' => $unixTimeTodayEnd]
  307. ];
  308. if (!isset($returnValues[$returnRange])) {
  309. $returnRange = 'today';
  310. }
  311. return "AND answereddatestamp>='" . $returnValues[$returnRange]['start'] . "' AND answereddatestamp<='" . $returnValues[$returnRange]['end'] . "'";
  312. }
  313. }