1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 namespace tool_brickfield\local\tool; 18 19 use tool_brickfield\manager; 20 21 /** 22 * Class printable. 23 * 24 * @package tool_brickfield 25 * @copyright 2020 onward: Brickfield Education Labs, www.brickfield.ie 26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 27 */ 28 class printable extends tool { 29 30 /** 31 * Provide a name for this tool, suitable for display on pages. 32 * @return mixed|string 33 * @throws \coding_exception 34 */ 35 public static function toolname(): string { 36 return get_string('printable:toolname', 'tool_brickfield'); 37 } 38 39 /** 40 * Provide a short name for this tool, suitable for menus and selectors. 41 * @return mixed|string 42 * @throws \coding_exception 43 */ 44 public static function toolshortname(): string { 45 return get_string('printable:toolshortname', 'tool_brickfield'); 46 } 47 48 /** 49 * Provide a lowercase name identifying this plugin. Should really be the same as the directory name. 50 * @return string 51 */ 52 public function pluginname(): string { 53 return 'printable'; 54 } 55 56 /** 57 * Return the data for renderer / template display. 58 * @return \stdClass 59 * @throws \coding_exception 60 * @throws \dml_exception 61 */ 62 protected function fetch_data(): \stdClass { 63 global $DB; 64 65 $filter = $this->get_filter(); 66 if (!$filter->has_course_filters()) { 67 return (object)[ 68 'valid' => false, 69 'error' => get_string('error:nocoursespecified', 'tool_brickfield'), 70 ]; 71 } else if (!$filter->validate_filters()) { 72 return (object)[ 73 'valid' => false, 74 'error' => $filter->get_errormessage(), 75 ]; 76 } 77 78 $data = (object)[ 79 'valid' => true, 80 'error' => '', 81 ]; 82 83 $config = get_config(manager::PLUGINNAME); 84 $perpage = isset($config->perpagefix) ? $config->perpagefix : $config->perpage; 85 86 list($wheresql, $params) = $filter->get_course_sql(); 87 88 $combo = []; 89 $sqlcombo = 'SELECT distinct '.$DB->sql_concat_join("''", ['area.component', 'area.contextid']).' as tmpid, 90 sum(res.errorcount) 91 FROM {' . manager::DB_AREAS . '} area 92 INNER JOIN {' . manager::DB_CONTENT . '} ch ON ch.areaid = area.id AND ch.iscurrent = 1 93 INNER JOIN {' . manager::DB_RESULTS . '} res ON res.contentid = ch.id 94 WHERE 1=1 ' . $wheresql . ' 95 group by area.component, area.contextid'; 96 $combodata = $DB->get_records_sql_menu($sqlcombo, $params); 97 98 $combo['total'] = count($combodata); 99 $combo['failed'] = 0; 100 foreach ($combodata as $count) { 101 if ($count != 0) { 102 $combo['failed']++; 103 } 104 } 105 $combo['passed'] = ($combo['total'] - $combo['failed']); 106 107 $data->combodata = $combo; 108 109 $sql = 'SELECT che.checkgroup, SUM(res.errorcount) as errorinstances 110 FROM {' . manager::DB_AREAS . '} area 111 INNER JOIN {' . manager::DB_CONTENT . '} ch ON ch.areaid = area.id AND ch.iscurrent = 1 112 INNER JOIN {' . manager::DB_RESULTS . '} res ON res.contentid = ch.id 113 INNER JOIN {' . manager::DB_CHECKS . '} che ON che.id = res.checkid 114 WHERE 1=1 ' . $wheresql . ' GROUP BY che.checkgroup 115 ORDER BY che.checkgroup'; 116 117 $groupdata = $DB->get_records_sql($sql, $params); 118 119 $data->groupdata = $groupdata; 120 121 // Adding check displaynames from language strings. 122 123 $wheresql = ' and area.courseid = ?'; 124 $params = [$filter->courseid]; 125 126 $sql4 = 'SELECT area.component, sum(res.errorcount) as errorsum 127 FROM {' . manager::DB_AREAS . '} area 128 INNER JOIN {' . manager::DB_CONTENT . '} ch ON ch.areaid = area.id AND ch.iscurrent = 1 129 INNER JOIN {' . manager::DB_RESULTS . '} res ON res.contentid = ch.id 130 WHERE 1=1 ' . $wheresql . ' GROUP BY area.component 131 ORDER BY errorsum DESC'; 132 $toptargetdataraw = $DB->get_records_sql($sql4, $params, 0, 5); 133 $toptargetdata = []; 134 foreach ($toptargetdataraw as $top) { 135 $top->component = tool::get_module_label($top->component); 136 if ($top->errorsum != 0) { 137 $toptargetdata[] = $top; 138 } 139 } 140 $data->toptargetdata = $toptargetdata; 141 142 $sql3 = 'SELECT che.shortname, sum(res.errorcount) as checkcount 143 FROM {' . manager::DB_AREAS . '} area 144 INNER JOIN {' . manager::DB_CONTENT . '} ch ON ch.areaid = area.id AND ch.iscurrent = 1 145 INNER JOIN {' . manager::DB_RESULTS . '} res ON res.contentid = ch.id 146 INNER JOIN {' . manager::DB_CHECKS . '} che ON che.id = res.checkid 147 WHERE 1=1 ' . $wheresql . ' AND res.errorcount >= ? GROUP BY che.shortname 148 ORDER BY checkcount DESC'; 149 $params[] = 1; 150 $checkcountdata = $DB->get_records_sql($sql3, $params, 0, 5); 151 foreach ($checkcountdata as $key => &$cdata) { 152 $cdata->checkname = self::get_check_description($key); 153 } 154 $data->checkcountdata = $checkcountdata; 155 156 $sqltar = 'SELECT distinct '.$DB->sql_concat_join("''", ['area.component', 'area.contextid']).' as tmpid, 157 component, SUM(errorcount) as errorsum 158 FROM {' . manager::DB_AREAS . '} area 159 INNER JOIN {' . manager::DB_CONTENT . '} ch ON ch.areaid = area.id AND ch.iscurrent = 1 160 INNER JOIN {' . manager::DB_RESULTS . '} res ON res.contentid = ch.id 161 WHERE 1=1 '.$wheresql.' 162 GROUP BY area.component, area.contextid'; 163 $targetdata = $DB->get_records_sql($sqltar, $params); 164 165 $tarlabels = []; 166 $combotar = []; 167 foreach ($targetdata as $tar) { 168 if (!array_key_exists($tar->component, $combotar)) { 169 $combotar[$tar->component] = []; 170 $combotar[$tar->component]['total'] = 0; 171 $combotar[$tar->component]['failed'] = 0; 172 $tarlabels[$tar->component] = tool::get_module_label($tar->component); 173 } 174 $combotar[$tar->component]['total']++; 175 if ($tar->errorsum > 0) { 176 $combotar[$tar->component]['failed']++; 177 } 178 } 179 ksort($combotar); 180 $data->combotardata = $combotar; 181 $data->tarlabels = $tarlabels; 182 183 $errorsql = 'SELECT err.id as errid, res.id as resid, area.component, area.itemid, area.cmid, 184 che.shortname, err.linenumber as errline, err.htmlcode 185 FROM {' . manager::DB_AREAS . '} area 186 INNER JOIN {' . manager::DB_CONTENT . '} ch ON ch.areaid = area.id AND ch.iscurrent = 1 187 INNER JOIN {' . manager::DB_RESULTS . '} res ON res.contentid = ch.id 188 INNER JOIN {' . manager::DB_CHECKS . '} che ON che.id = res.checkid 189 INNER JOIN {' . manager::DB_ERRORS . '} err ON res.id = err.resultid WHERE 1=1 ' . $wheresql; 190 $errordata = $DB->get_records_sql($errorsql, $params, 0, $perpage); 191 192 foreach ($errordata as $err) { 193 $err->shortname = self::get_check_description($err->shortname); 194 // Truncating HTML with base64 image data, to avoid page overstretching. 195 $base64detected = parent::base64_img_detected($err->htmlcode); 196 if ($base64detected) { 197 $err->htmlcode = parent::truncate_base64($err->htmlcode); 198 } 199 } 200 201 $data->errordata = $errordata; 202 $data->errordetailscount = $perpage; 203 204 if ($filter->categoryid != 0) { 205 $data->countdata = count($filter->courseids); 206 } else { 207 $countsql = 'select count(distinct courseid) from {' . manager::DB_AREAS . '}'; 208 $countdata = $DB->count_records_sql($countsql, []); 209 $data->countdata = $countdata; 210 } 211 212 return $data; 213 } 214 215 /** 216 * Get the HTML output for display. 217 * @return mixed 218 */ 219 public function get_output() { 220 global $PAGE; 221 222 $data = $this->get_data(); 223 $filter = $this->get_filter(); 224 225 $renderer = $PAGE->get_renderer('tool_brickfield', 'printable'); 226 if ($filter->target == 'pdf') { 227 $renderer->pdf_renderer($data, $filter); 228 return ''; 229 } else if ($filter->target == 'html') { 230 $output = $renderer->header(); 231 return $output . $renderer->display($data, $filter); 232 } else { 233 return $renderer->display($data, $filter); 234 } 235 } 236 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body