AutorÃa | Ultima modificación | Ver Log |
<?php// This file is part of Moodle - http://moodle.org///// Moodle is free software: you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation, either version 3 of the License, or// (at your option) any later version.//// Moodle is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with Moodle. If not, see <http://www.gnu.org/licenses/>.namespace tool_brickfield\output\printable;use tool_brickfield\local\tool\bfpdf;use core\chart_bar;use core\chart_pie;use core\chart_series;use tool_brickfield\accessibility;use tool_brickfield\area_base;use tool_brickfield\local\tool\filter;use tool_brickfield\manager;/*** tool_brickfield/printable renderer** @package tool_brickfield* @copyright 2020 onward: Brickfield Education Labs, https://www.brickfield.ie* @author Mike Churchward* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later*/class renderer extends \tool_brickfield\output\renderer {/*** Render the page containing the Printable report.** @param \stdClass $data Report data.* @param filter $filter Display filters.* @return String HTML showing charts.* @throws \coding_exception* @throws \dml_exception* @throws \moodle_exception*/public function display(\stdClass $data, filter $filter): string {$css = '';// Page data.$out = '';if (empty($filter->target)) {$linkname = get_string('printable:downloadpdf', 'tool_brickfield');$link = new \moodle_url(accessibility::get_plugin_url(),['tab' => 'printable','courseid' => $filter->courseid,'target' => 'pdf',]);$htmlicon = new \pix_icon('t/print', $linkname);$class = 'tool_brickfield_floatprinticon';$printlink = $this->action_link($link, $linkname, null, ['class' => $class, 'title' => $linkname], $htmlicon);}$out .= \html_writer::tag('h3', accessibility::get_title($filter, $data->countdata));$out .= !empty($printlink) ? $printlink : '';$div1 = \html_writer::div($this->pix_icon('f/award',get_string('totalactivities', manager::PLUGINNAME), manager::PLUGINNAME).get_string('totalactivitiescount', manager::PLUGINNAME, $data->combodata['total']), '',['class' => 'col-sm-3'.$css]);$div2 = \html_writer::div($this->pix_icon('f/done2',get_string('passed', manager::PLUGINNAME), manager::PLUGINNAME).get_string('passedcount', manager::PLUGINNAME, $data->combodata['passed']), '',['class' => 'col-sm-3'.$css]);$div3 = \html_writer::div($this->pix_icon('f/error',get_string('failed', manager::PLUGINNAME), manager::PLUGINNAME).get_string('failedcount', manager::PLUGINNAME, $data->combodata['failed']), '',['class' => 'col-sm-3'.$css]);$out .= \html_writer::div($div1.$div2.$div3, '', ['id' => 'rowa', 'class' => 'row h4']);$out .= \html_writer::div(' '); // Padding row.$str1 = \html_writer::tag('h4', get_string('toperrors', manager::PLUGINNAME));$table = new \html_table();$table->head = [get_string('tblcheck', manager::PLUGINNAME),get_string('count', manager::PLUGINNAME),];$table->size = ['80%', '20%'];$table->align = ['left', 'center'];$data->checkcountdata = !empty($data->checkcountdata) ? $data->checkcountdata : [];foreach ($data->checkcountdata as $key => $value) {if ($value->checkcount > 0) {$table->data[] = [$value->checkname, $value->checkcount];}}if (count($data->checkcountdata) > 0) {$str1 .= \html_writer::table($table, true);} else {$str1 .= \html_writer::tag('p', get_string('noerrorsfound', manager::PLUGINNAME));}$out .= \html_writer::start_div('row', ['id' => 'row2']);$out .= \html_writer::div($str1, '', ['class' => 'col-sm-4']);$str2 = \html_writer::tag('h4', get_string('toptargets', manager::PLUGINNAME));$table = new \html_table();$table->head = [get_string('tbltarget', manager::PLUGINNAME),get_string('count', manager::PLUGINNAME),];$table->size = ['80%', '20%'];$table->align = ['left', 'center'];$data->toptargetdata = !empty($data->toptargetdata) ? $data->toptargetdata : [];$table->data = $data->toptargetdata;if (count($data->toptargetdata) > 0) {$str2 .= \html_writer::table($table, true);} else {$str2 .= \html_writer::tag('p', get_string('noerrorsfound', manager::PLUGINNAME));}$out .= \html_writer::div($str2, '', ['class' => 'col-sm-4']);$str3 = \html_writer::tag('h4', get_string('taberrors', manager::PLUGINNAME));$table = new \html_table();$table->head = [get_string('checktype', manager::PLUGINNAME),get_string('count', manager::PLUGINNAME),];$table->size = ['80%', '20%'];$table->align = ['left', 'center'];foreach ($data->groupdata as $key => $group) {$checkgroup = area_base::checkgroup_name($key);$tmplabel = get_string('checktype:' . $checkgroup, manager::PLUGINNAME);$icon = $this->pix_icon('f/' . $checkgroup, $tmplabel, manager::PLUGINNAME);$table->data[] = [get_string('checktype:' . $checkgroup, manager::PLUGINNAME), $group->errorinstances];}$str3 .= \html_writer::table($table, true);$out .= \html_writer::div($str3, '', ['class' => 'col-sm-4']);$out .= \html_writer::end_div(); // End row2.$out .= \html_writer::start_div('row', ['id' => 'row3']);foreach ($data->combotardata as $key => &$combotar) {$combotar['passed'] = $combotar['total'] - $combotar['failed'];$combos[] = $combotar['total'] - $combotar['failed'];$combosf[] = $combotar['failed'];}$str4 = \html_writer::tag('h4', get_string('targetratio', manager::PLUGINNAME));$table = new \html_table();$table->head = [get_string('tbltarget', manager::PLUGINNAME),get_string('passed', manager::PLUGINNAME),get_string('failed', manager::PLUGINNAME),get_string('total')];foreach ($data->combotardata as $tar => $tarvalue) {$table->data[] = [$data->tarlabels[$tar],$tarvalue['passed'], $tarvalue['failed'], $tarvalue['total']];}$table->size = ['40%', '20%', '20%', '20%'];$table->align = ['left', 'center', 'center', 'center'];$str4 .= \html_writer::table($table, true);$out .= \html_writer::div($str4, '', ['class' => 'col-sm-4']);$str5 = \html_writer::tag('h4', get_string('titleerrorscount', manager::PLUGINNAME, $data->errordetailscount));$table = new \html_table();$table->head = [get_string('tbltarget', manager::PLUGINNAME),get_string('tblcheck', manager::PLUGINNAME),get_string('tblline', manager::PLUGINNAME),get_string('tblhtmlcode', manager::PLUGINNAME)];$data->errordata = !empty($data->errordata) ? $data->errordata : [];foreach ($data->errordata as $err) {$err->htmlcode = htmlentities($err->htmlcode, ENT_COMPAT);$row = [$data->tarlabels[$err->component], $err->shortname, $err->errline, $err->htmlcode];$table->data[] = $row;}$table->size = ['10%', '25%', '5%', '60%'];if (count($data->errordata) > 0) {$str5 .= \html_writer::table($table, true);} else {$str5 .= \html_writer::tag('p', get_string('noerrorsfound', manager::PLUGINNAME));}$out .= \html_writer::div($str5, '', ['class' => 'col-sm-8']);$out .= \html_writer::end_div(); // End row3.if ($filter->target == 'pdf') {// Converting divs to spans for better PDF display.$out = str_replace(['<div>', '</div>'], ['<span>', '</span>'], $out);}return $out;}/*** Return the path to use for PDF images.** @return string*/private function image_path(): string {global $CFG;return $CFG->wwwroot . '/admin/tool/brickfield/pix/pdf/';}/*** Renders the accessability report using the pdflib.** @param \stdClass $data Report data.* @param filter $filter Display filters.* @throws \coding_exception* @throws \dml_exception* @throws \moodle_exception* @return void*/public function pdf_renderer(\stdClass $data, filter $filter) {$pdf = new bfpdf();$pdf->setFooterFont(Array('Helvetica', '', 10));$pdf->setPrintHeader(false);$pdf->SetCreator(PDF_CREATOR);$pdf->SetAuthor('Brickfield Accessibility Report');$pdf->SetTitle('Brickfield Accessibility Report');$pdf->SetFont('Helvetica');// Set default monospaced font.$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);// Set margins.$pdf->SetMargins(20, 20, 20, 100);$pdf->AddPage('P');$errorreporting = error_reporting(0);// Get current date for current user.$date = new \DateTime("now", \core_date::get_user_timezone_object());$pdf->SetLineWidth(0.0);$html = '<h1>' . get_string('accessibilityreport', manager::PLUGINNAME) . '</h1><h2>'. accessibility::get_title($filter, $data->countdata) .'</h2><p>' . userdate($date->getTimestamp()) . '</p><table cellspacing="0" cellpadding="1"><tr><td><img src="' . $this->image_path() . 'tachometer-alt-solid.svg" width="15" height="15">' .get_string('totalactivitiescount', manager::PLUGINNAME, $data->combodata['total']) .'</td><td><img src="' . $this->image_path() . 'check-square-regular.svg" width="15" height="15">' .get_string('passedcount', manager::PLUGINNAME, $data->combodata['passed']) .'</td><td><img src="' . $this->image_path() . 'times-circle-regular.svg" width="15" height="15">' .get_string('failedcount', manager::PLUGINNAME, $data->combodata['failed']) .'</td></tr></table>';$pdf->writeHTML($html);if (!empty($data->checkcountdata)) {$pdf->writeHTML($this->get_errors_table($data));$tablegroup = '<table><tr><td width="45%">'. $this->get_group_table($data) . '</td><td width="10%"></td><td width="45%">'. $this->get_inaccessible_table($data) . '</td></tr></table>';$pdf->writeHTML($tablegroup);$pdf->AddPage('P');} else {$pdf->writeHTML('<div>'.get_string('noerrorsfound', manager::PLUGINNAME).'</div><div></div>');}$pdf->writeHTML($this->get_ratio_table($data));// Output the pdf.@$pdf->Output(get_string('pdf:filename', 'tool_brickfield', $filter->courseid).'_' . userdate($date->getTimestamp(), '%Y_%m_%d') . '.pdf', 'D');error_reporting($errorreporting);}/*** Builds the HTML for a styled table used in the pdf report.** @param array $headers The headers of the table.* @param array $data The table data.* @param string $title The title of the table.* @param array $widths The widths of the table columns.* @return string The HTML code of the table.*/public function render_table(array $headers, array $data, string $title, array $widths): string {$numheaders = count($headers);$html = '';$html .= '<table cellspacing="0" cellpadding="5" style="background-color: #ffffff;">';$html .= '<tr><td style="border-bottom:.1 solid #333333;" colspan="'.$numheaders.'"><h3>'.$title.'</h3></td></tr>';$html .= '<tr>';for ($i = 0; $i < $numheaders; ++$i) {$align = $i > 0 ? "center" : "left";$html .= '<th style="text-align:'.$align.';" width="'.$widths[$i].'">';$html .= '<b>'.$headers[$i].'</b>';$html .= '</th>';}$html .= '</tr>';$j = 1;foreach ($data as $row) {++$j;$color = $j % 2 == 1 ? "#FFFFFF" : "#F2F2F2";$html .= '<tr border ="1" style="background-color:'.$color.';">';for ($i = 0; $i < $numheaders; ++$i) {$align = $i > 0 ? "center" : "left";$html .= '<td width="'.$widths[$i].'" style="text-align:'.$align.';, background-color:'.$color.';">';$html .= $row[$i];$html .= '</td>';}$html .= '</tr>';}$html .= '</table>';return $html;}/*** Gets the Activity Pass Ratio table.** @param \stdClass $data Report data.* @return string The HTML code of the table.*/public function get_ratio_table(\stdClass $data): string {$headers = [get_string('tbltarget', manager::PLUGINNAME),get_string('passed', manager::PLUGINNAME),get_string('failed', manager::PLUGINNAME),get_string('total')];$tabledata = [];foreach ($data->combotardata as $tar => $tarvalue) {$tabledata[] = [$data->tarlabels[$tar],$tarvalue['total'] - $tarvalue['failed'],$tarvalue['failed'],$tarvalue['total']];}return $this->render_table($headers,$tabledata,get_string('targetratio', manager::PLUGINNAME),["40%", "20%", "20%", "20%"]);}/*** Gets the Check Errors table.** @param \stdClass $data Report data.* @return string The HTML code of the table.*/public function get_group_table(\stdClass $data): string {$headers = [get_string('checktype', manager::PLUGINNAME),get_string('count', manager::PLUGINNAME),];$tabledata = [];// Numbers are constants from \tool_brickfield\area_base::checkgroup.$icons = [area_base::CHECKGROUP_IMAGE => $this->image_path() . 'image-regular.svg',area_base::CHECKGROUP_LAYOUT => $this->image_path() . 'th-large-solid.svg',area_base::CHECKGROUP_LINK => $this->image_path() . 'link.png',area_base::CHECKGROUP_MEDIA => $this->image_path() . 'play-circle-regular.svg',area_base::CHECKGROUP_TABLE => $this->image_path() . 'table-solid.svg',area_base::CHECKGROUP_TEXT => $this->image_path() . 'font-solid.svg',];foreach ($data->groupdata as $key => $group) {$checkgroup = area_base::checkgroup_name($key);$icon = $icons[$key];$tabledata[] = ['<img src="'.$icon.'" width="15" height="15">' . ' ' .get_string('checktype:' . $checkgroup, manager::PLUGINNAME), $group->errorinstances];}return $this->render_table($headers,$tabledata,get_string('taberrors', manager::PLUGINNAME),["70%", "30%"]);}/*** Gets the Failed Activities table.** @param \stdClass $data Report data.* @return string The HTML code of the table.*/public function get_inaccessible_table(\stdClass $data): string {$headers = [get_string('tbltarget', manager::PLUGINNAME),get_string('count', manager::PLUGINNAME)];$tabledata = [];foreach ($data->toptargetdata as $key => $value) {if ($value->errorsum > 0) {$tabledata[] = [$value->component, $value->errorsum];}}return $this->render_table($headers,$tabledata,get_string('toptargets', manager::PLUGINNAME),["70%", "30%"]);}/*** Gets the Top Errors table.** @param \stdClass $data Report data.* @return string The HTML code of the table.*/public function get_errors_table(\stdClass $data): string {$headers = [get_string('tblcheck', manager::PLUGINNAME), get_string('count', manager::PLUGINNAME)];$tabledata = [];$data->checkcountdata = !empty($data->checkcountdata) ? $data->checkcountdata : [];foreach ($data->checkcountdata as $value) {if ($value->checkcount > 0) {$tabledata[] = [$value->checkname, $value->checkcount];}}return $this->render_table($headers, $tabledata, get_string('toperrors', manager::PLUGINNAME), ["80%", "20%"]);}}