PageRenderTime 66ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/include/classes/exportRpt/exportCSV.class.php

https://github.com/atutor/AChecker
PHP | 399 lines | 229 code | 54 blank | 116 comment | 103 complexity | 821a1612b5c39a7fb8e6318f2d33becd MD5 | raw file
  1. <?php
  2. /************************************************************************/
  3. /* AChecker */
  4. /************************************************************************/
  5. /* Copyright (c) 2008 - 2011 */
  6. /* Inclusive Design Institute */
  7. /* */
  8. /* This program is free software. You can redistribute it and/or */
  9. /* modify it under the terms of the GNU General Public License */
  10. /* as published by the Free Software Foundation. */
  11. /************************************************************************/
  12. // $Id:
  13. /**
  14. * acheckerCSV
  15. * Class to generate error report in CSV file
  16. * for each of types: known, likely, potential, html, css and all selected
  17. * @access public
  18. * @author Casian Olga
  19. */
  20. if (!defined("AC_INCLUDE_PATH")) exit;
  21. include_once(AC_INCLUDE_PATH. "classes/DAO/GuidelinesDAO.class.php");
  22. // end of line; system dependent
  23. if (PHP_EOL == "\r\n") {
  24. define(EOL, "\r\n");
  25. } else {
  26. define(EOL, "\n");
  27. }
  28. // delimiter
  29. define(DELIM, ",");
  30. class acheckerCSV {
  31. // all private
  32. // arrays that contain all data about errors of specific type
  33. var $known = array();
  34. var $likely = array();
  35. var $potential = array();
  36. var $html = array();
  37. var $css = array();
  38. // numbers of errors to display for each problem type
  39. var $error_nr_known = 0;
  40. var $error_nr_likely = 0;
  41. var $error_nr_potential = 0;
  42. var $error_nr_html = 0;
  43. var $error_nr_css = 0;
  44. // css and html error messages
  45. // css validator is only available at validating url, not at validating a uploaded file or pasted html
  46. var $css_error = '';
  47. var $html_error = '';
  48. var $achecker_file_url = 'http://www.atutor.ca/achecker/';
  49. /**
  50. * public
  51. * error arrays and numbers setter
  52. * @param
  53. * $known, $likely, $potential: arrays that contain errors of specific type
  54. * $html, $css: arrays of validation errors
  55. * $error_nr_known, $error_nr_likely, $error_nr_potential: nr of errors
  56. * $error_nr_html, $error_nr_css: nr of errors
  57. * $css_error: empty if css validation was required with URL input, otherwise string with error msg
  58. */
  59. function acheckerCSV($known, $likely, $potential, $html, $css,
  60. $error_nr_known, $error_nr_likely, $error_nr_potential, $error_nr_html, $error_nr_css, $css_error, $html_error)
  61. {
  62. $this->known = $known;
  63. $this->likely = $likely;
  64. $this->potential = $potential;
  65. $this->html = $html;
  66. $this->css = $css;
  67. $this->error_nr_known = $error_nr_known;
  68. $this->error_nr_likely = $error_nr_likely;
  69. $this->error_nr_potential = $error_nr_potential;
  70. $this->error_nr_html = $error_nr_html;
  71. $this->error_nr_css = $error_nr_css;
  72. $this->css_error = $css_error;
  73. $this->html_error = $html_error;
  74. }
  75. /**
  76. * public
  77. * main process of creating file
  78. * @param
  79. * $title: validated content title (fount in <title> tag); if empty title will not be displayed
  80. * $input_content_type: 'file', 'paste' or http://file_path
  81. * $problem: problem type on which to create report (can be: known, likely, potential, html, css or all)
  82. * $_gids: array of guidelines that were used as testing criteria
  83. */
  84. public function getCSV($problem, $input_content_type, $title, $_gids)
  85. {
  86. // set filename
  87. $date = AC_date('%Y-%m-%d');
  88. $time = AC_date('%H-%i-%s');
  89. $filename = 'achecker_'.$date.'_'.$time;
  90. $file_content = $this->getInfo($input_content_type, $title, $_gids, $date, $time);
  91. if ($problem == 'all') {
  92. $file_content .= $this->getResultSection('known');
  93. $file_content .= $this->getResultSection('likely');
  94. $file_content .= $this->getResultSection('potential');
  95. if ($this->error_nr_html != -1) $file_content .= $this->getHTML();
  96. if ($this->error_nr_css != -1) $file_content .= $this->getCSS();
  97. } else if ($problem == 'css') {
  98. $file_content .= $this->getCSS();
  99. } else if ($problem == 'html') {
  100. $file_content .= $this->getHTML();
  101. } else {
  102. $file_content .= $this->getResultSection($problem);
  103. }
  104. $path = AC_EXPORT_RPT_DIR.$filename.'.csv';
  105. $handle = fopen($path, 'w');
  106. fwrite($handle, pack("CCC",0xef,0xbb,0xbf));
  107. fwrite($handle, $file_content);
  108. fclose($handle);
  109. return $path;
  110. }
  111. /**
  112. * private
  113. * writes AChecker info, date, time [, url] [, title] and guidelines
  114. * returns them as CSV string
  115. * @param
  116. * $input_content_type: 'file', 'paste' or http://file_path
  117. * $title: validated content title (fount in <title> tag); if empty title will not be displayed
  118. * $_gids: array of guidelines that were used as testing criteria
  119. * $date: date when function to create file called (showed in file title and inside document)
  120. * $time: time when function to create file called (showed in file title and inside document)
  121. */
  122. private function getInfo($input_content_type, $title, $_gids, $date, $time)
  123. {
  124. // achecker info
  125. $file_content = _AC('file_title').DELIM.'version '.VERSION.DELIM
  126. .$this->prepareStr(_AC('file_description')).EOL.$this->achecker_file_url.EOL.EOL;
  127. // date, time
  128. $file_content .= str_replace("-", ".", $date).' '.str_replace("-", ":", $time).EOL;
  129. // test info
  130. if ($input_content_type != 'file' && $input_content_type != 'paste') {
  131. $file_content .= _AC('file_source_url').DELIM.$input_content_type.EOL;
  132. } else {
  133. $file_content .= EOL;
  134. }
  135. if ($title != '') {
  136. $file_content .= _AC('file_source_title').DELIM.$title.EOL;
  137. } else {
  138. $file_content .= EOL;
  139. }
  140. // guidelines
  141. $file_content .= EOL;
  142. $guidelinesDAO = new GuidelinesDAO();
  143. $guideline_rows = $guidelinesDAO->getGuidelineByIDs($_gids);
  144. if (is_array($guideline_rows)) {
  145. foreach ($guideline_rows as $id => $row) {
  146. $file_content .= $row["abbr"].DELIM._AC($row["long_name"]).EOL;
  147. }
  148. }
  149. return $file_content;
  150. }
  151. /**
  152. * private
  153. * prepares given string to be written as single CSV cell (considers '"', ';', ',', '\n')
  154. * if $str has new lines it's better to replace them by '' or ' '
  155. * @param
  156. * $str: string that needs to be prepaired
  157. * return prepaired $str, one CSV cell
  158. */
  159. private function prepareStr($str)
  160. {
  161. // " => "" and "$str"
  162. if (strstr($str, '"')) {
  163. $a = explode('"', $str);
  164. $str = implode('""', $a);
  165. $str = '"'.$str.'"';
  166. }
  167. // \n | ; | , | " => "$str"
  168. if (($str[0] != '"' && $str[strlen($str)-1] != '"') &&
  169. ((strstr($str, "\n") != false) || (strstr($str, ";") != false) || (strstr($str, ",") != false))) {
  170. $str = '"'.$str.'"';
  171. }
  172. return $str;
  173. }
  174. /**
  175. * private
  176. * writes result section for 1 problem type
  177. * @param
  178. * $problem_type: known, potential or likely; corresponding array in class should be set before calling
  179. * return result section as CSV string
  180. */
  181. private function getResultSection($problem_type)
  182. {
  183. if ($problem_type == 'known') {
  184. $array = $this->known;
  185. $nr = $this->error_nr_known;
  186. $file_content .= EOL._AC("known_problems").': '.$nr.EOL;
  187. } else if ($problem_type == 'likely') {
  188. $array = $this->likely;
  189. $nr = $this->error_nr_likely;
  190. $file_content .= EOL._AC("likely_problems").': '.$nr.EOL;
  191. } else if ($problem_type == 'potential') {
  192. $array = $this->potential;
  193. $nr = $this->error_nr_potential;
  194. $file_content .= EOL._AC("potential_problems").': '.$nr.EOL;
  195. }
  196. // show congratulations if no errors found
  197. if ($nr == 0) {
  198. // congrats message
  199. $file_content .= _AC("congrats_no_$problem_type").EOL;
  200. }
  201. // Display the list of problems, including the problems that the user has made pass decisions on.
  202. if (is_array($array) && count($array) > 0) { // make report on errors
  203. if ($problem_type == 'known') {
  204. $file_content .= _AC("file_repair").DELIM._AC("file_problem").DELIM._AC("file_css").DELIM._AC("file_img").EOL;
  205. foreach ($array as $error) {
  206. // line and column + error text
  207. $file_content .= $error['line_text'].' '.$error['line_nr'].', '.$error['col_text'].' '.$error['col_nr']
  208. .': '.$this->prepareStr(strip_tags($error['error'])).EOL;
  209. // repair
  210. $str = str_replace(EOL, "", $error['repair']['detail']);
  211. $file_content .= $this->prepareStr(strip_tags($error['repair']['label'].': '.$str)).DELIM;
  212. // html
  213. $file_content .= $this->prepareStr(html_entity_decode($error['html_code'], ENT_COMPAT, 'UTF-8')).DELIM;
  214. // css
  215. if ($error['css_code']) {
  216. $pattern = "/CSS.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s/";
  217. if (preg_match($pattern, strip_tags($error['css_code']), $matches)) {
  218. $file_content .= $this->prepareStr($matches[0]).DELIM;
  219. }
  220. } else $file_content .= "".DELIM;
  221. // img
  222. if ($error['image']) {
  223. $file_content .= $this->prepareStr($error['image']['src']).EOL;
  224. } else $file_content .= "".DELIM.EOL;
  225. } // end foreach $error
  226. }
  227. // likely and potential. needed to show 'passed', 'failed' or 'no decision'
  228. else {
  229. $file_content .= _AC("file_problem").DELIM._AC("file_css").DELIM._AC("file_img");
  230. if (isset($_SESSION['user_id'])) {
  231. $file_content .= DELIM._AC("file_decision");
  232. }
  233. $file_content .= EOL;
  234. foreach ($array as $category) { // with decision, no decision
  235. foreach ($category as $error) {
  236. // line and column + error text
  237. $file_content .= $error['line_text'].' '.$error['line_nr'].', '.$error['col_text'].' '.$error['col_nr']
  238. .': '.$this->prepareStr(strip_tags($error['error'])).EOL;
  239. // html
  240. $file_content .= $this->prepareStr(html_entity_decode($error['html_code'], ENT_COMPAT, 'UTF-8')).DELIM;
  241. // css
  242. if ($error['css_code']) {
  243. $pattern = "/CSS.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s.*\s/";
  244. if (preg_match($pattern, strip_tags($error['css_code']), $matches)) {
  245. $file_content .= $this->prepareStr($matches[0]).DELIM;
  246. }
  247. } else $file_content .= "".DELIM;
  248. // img
  249. if ($error['image']) {
  250. $file_content .= $this->prepareStr($error['image']['src']).DELIM;
  251. } else $file_content .= "".DELIM;
  252. // if user is logged in display 'passed', 'failed' or 'no decision'
  253. if (isset($_SESSION['user_id'])) {
  254. // decision
  255. if ($error['decision'] == 'true') $file_content .= _AC('file_passed');
  256. else if ($error['decision'] == false) $file_content .= _AC('file_failed');
  257. else if ($error['decision'] == 'none') $file_content .= _AC('file_no_decision');
  258. } // end if user is logged in
  259. $file_content .= EOL;
  260. } // end foreach $error
  261. } // end foreach $category
  262. }
  263. }
  264. return $file_content;
  265. }
  266. /**
  267. * private
  268. * writes report for HTML validation; corresponding array in class should be set before calling
  269. * return HTML validation result as CSV string
  270. */
  271. private function getHTML()
  272. {
  273. $file_content .= EOL._AC("html_validation_result").': '.$this->error_nr_html.DELIM.strip_tags(_AC("html_validator_provided_by")).EOL;
  274. // str with error type and nr of errors
  275. if ($this->error_nr_html == -1) {
  276. $file_content .= _AC("html_validator_disabled").EOL;
  277. } else if ($this->error_nr_html == 0 && $this->html_error == '') {
  278. // show congratulations if no errors found
  279. // no html validation errors, passed
  280. $file_content .= _AC("congrats_html_validation").EOL;
  281. } else if($this->error_nr_html == 0 && $this->html_error != '') {
  282. // html validation errors
  283. $file_content .= $this->html_error.EOL;
  284. } else { // else make report on errors
  285. $file_content .= _AC("file_problem").DELIM._AC("file_text").EOL;
  286. foreach ($this->html as $error) {
  287. // line and column + error text
  288. $file_content .= $this->prepareStr(_AC('line')." ".$error['line'].", "._AC('column')." ".$error['col'].": ".html_entity_decode(strip_tags($error['err']))).EOL;
  289. // html
  290. $file_content .= $this->prepareStr(html_entity_decode($error['html_1'].$error['html_2'].$error['html_3'], ENT_COMPAT, 'UTF-8')).DELIM;
  291. // text
  292. if ($error['text']) {
  293. $str = str_replace("\n", "", strip_tags(html_entity_decode($error['text'])));
  294. $str = str_replace("\r", "", strip_tags(html_entity_decode($error['text'])));
  295. $str = preg_replace("/ {2,}/", " ", $str);
  296. $file_content .= $this->prepareStr($str).EOL;
  297. } else $file_content .= "".EOL;
  298. } // end foreach $error
  299. }
  300. return $file_content;
  301. }
  302. /**
  303. * private
  304. * writes report for CSS validation; corresponding array in class should be set before calling
  305. * return CSS validation result as CSV string
  306. */
  307. private function getCSS()
  308. {
  309. $file_content .= EOL._AC("css_validation_result").': '.$this->error_nr_css.DELIM.strip_tags(_AC("css_validator_provided_by")).EOL;
  310. if ($this->css_error == '' && $this->error_nr_css == -1) {
  311. // css validator is disabled
  312. $file_content .= _AC("css_validator_disabled").EOL;
  313. }
  314. if ($this->css_error != '') {
  315. // css validator is only available at validating url, not at validating a uploaded file or pasted html
  316. $file_content .= $this->css_error.EOL;
  317. } else if ($this->error_nr_css == 0) {
  318. // show congratulations if no errors found
  319. $file_content .= _AC("congrats_css_validation").EOL;
  320. } else {
  321. $file_content .= $this->prepareStr(_AC('line')).DELIM.$this->prepareStr(_AC('html_tag')).DELIM.$this->prepareStr(_AC('error')).EOL;
  322. foreach($this->css as $uri => $group) {
  323. // uri
  324. $file_content .= "URI: ".$uri.EOL;
  325. foreach($group as $error) {
  326. // line
  327. $file_content .= $error['line'];
  328. // code
  329. if ($error['code'] != '') $file_content .= DELIM.$this->prepareStr($error['code']);
  330. else $file_content .= DELIM."";
  331. // parse
  332. if ($error['parse'] != '') {
  333. $str = str_replace("\n", "", strip_tags(html_entity_decode($error['parse'])));
  334. $str = str_replace("\r", "", strip_tags(html_entity_decode($error['parse'])));
  335. $str = preg_replace("/ {2,}/", " ", $str);
  336. $file_content .= DELIM.$this->prepareStr($str).EOL;
  337. }
  338. else $file_content .= DELIM."".EOL;
  339. } // end foreach error
  340. } // end foreach group
  341. }
  342. return $file_content;
  343. }
  344. }
  345. ?>