Permalink
Browse files

fixed undefined index line 147 in "remove_column" function

  • Loading branch information...
1 parent 9afaefa commit d4817b731790114c258bafe08ae4a20bb16232c6 gbateson committed Nov 4, 2005
Showing with 749 additions and 746 deletions.
  1. +749 −746 mod/hotpot/report/default.php
View
1,495 mod/hotpot/report/default.php
@@ -1,746 +1,749 @@
-<?PHP // $Id$
-
-////////////////////////////////////////////////////////////////////
-/// Default class for report plugins
-///
-/// Doesn't do anything on it's own -- it needs to be extended.
-/// This class displays quiz reports. Because it is called from
-/// within /mod/quiz/report.php you can assume that the page header
-/// and footer are taken care of.
-///
-/// This file can refer to itself as report.php to pass variables
-/// to itself - all these will also be globally available. You must
-/// pass "id=$cm->id" or q=$quiz->id", and "mode=reportname".
-////////////////////////////////////////////////////////////////////
-
-// Included by ../report.php
-
-class hotpot_default_report {
-
- function display($hotpot, $cm, $course, $users, $attempts, $questions, $options) {
- /// This function just displays the report
- // it is replaced by the "display" functions in the scripts in the "report" folder
- return true;
- }
-
- function add_question_headings(&$questions, &$table, $align='center', $size=50, $wrap=false, $fontsize=0) {
- $count = count($questions);
- for ($i=0; $i<$count; $i++) {
- $table->head[] = get_string('questionshort', 'hotpot', $i+1);
- if (isset($table->align)) {
- $table->align[] = $align;
- }
- if (isset($table->size)) {
- $table->size[] = $size;
- }
- if (isset($table->wrap)) {
- $table->wrap[] = $wrap;
- }
- if (isset($table->fontsize)) {
- $table->fontsize[] = $fontsize;
- }
- }
-
- }
-
- function set_legend(&$table, &$q, &$value, &$question) {
- // $q is the question number
- // $value is the value (=text) of the answer
-
- // check the legend is required
- if (isset($table->legend) && isset($value)) {
-
- // create question details array, if necessary
- if (empty($table->legend[$q])) {
- $table->legend[$q] = array(
- 'name' => hotpot_get_question_name($question),
- 'answers' => array()
- );
- }
-
- // search for this $value in answers array for this $q(uestion)
- $i_max = count($table->legend[$q]['answers']);
- for ($i=0; $i<$i_max; $i++) {
- if ($table->legend[$q]['answers'][$i]==$value) {
- break;
- }
- }
-
- // add $value to answers array, if it was not there
- if ($i==$i_max) {
- $table->legend[$q]['answers'][$i] = $value;
- }
-
- // convert $value to alphabetic index (A, B ... AA, AB ...)
- $value = $this->dec_to_ALPHA($i);
- }
- }
- function create_legend_table(&$tables, &$table) {
-
- if (isset($table->legend)) {
-
- $legend->width = '*';
- $legend->tablealign = '*';
- $legend->border = isset($table->border) ? $table->border : NULL;
- $legend->cellpadding = isset($table->cellpadding) ? $table->cellpadding : NULL;
- $legend->cellspacing = isset($table->cellspacing) ? $table->cellspacing : NULL;
- $legend->tableclass = isset($table->tableclass) ? $table->tableclass : NULL;
-
- $legend->caption = get_string('reportlegend', 'hotpot');
- $legend->align = array('right', 'left');
- $legend->statheadercols = array(0);
-
- $legend->stat = array();
-
- // put the questions in order
- sort($table->legend);
-
- foreach($table->legend as $q=>$question) {
-
- $legend->stat[] = array(
- get_string('questionshort', 'hotpot', $q+1),
- $question['name']
- );
- foreach($question['answers'] as $a=>$answer) {
- $legend->stat[] = array(
- $this->dec_to_ALPHA($a),
- $answer
- );
- }
- }
-
- unset($table->legend);
- $tables[] = $legend;
- }
- }
- function dec_to_ALPHA($dec) {
- if ($dec < 26) {
- return chr(ord('A') + $dec);
- } else {
- return $this->dec_to_ALPHA(intval($dec/26)-1).$this->dec_to_ALPHA($dec % 26);
- }
- }
- function remove_column(&$table, $target_col) {
-
- if (is_array($table)) {
- unset($table[$target_col]);
- $table = array_values($table);
-
- } else if (is_object($table)) {
- $vars = get_object_vars($table);
- foreach ($vars as $name=>$value) {
- switch ($name) {
- case 'data' :
- case 'stat' :
- case 'foot' :
- $skipcol = array();
- $cells = &$table->$name;
-
- $row_max = count($cells);
- for ($row=0; $row<$row_max; $row++) {
-
- $i = 0; // index on $cells[$row]
- $col = 0;
- while ($col<$target_col && isset($cells[$row][$i])) {
-
- if (empty($skipcol[$col])) {
- $cell = $cells[$row][$i++];
- if (is_object($cell)) {
- if (isset($cell->rowspan) && is_numeric($cell->rowspan) && ($cell->rowspan>0)) {
- // skip cells below this one
- $skipcol[$col] = $cell->rowspan-1;
- }
- if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>0)) {
- // skip cells to the right of this one
- for ($c=1; $c<$cell->colspan; $c++) {
- if (empty($skipcol[$col+$c])) {
- $skipcol[$col+$c] = 1;
- } else {
- $skipcol[$col+$c] ++;
- }
- }
- }
- }
- } else {
- $skipcol[$col]--;
- }
- $col++;
- } // end while $col
- if ($col==$target_col && isset($cells[$row][$i])) {
- $this->remove_column($cells[$row], $i);
- }
- } // end for $row
- break;
- case 'head' :
- case 'align' :
- case 'class' :
- case 'fontsize' :
- case 'size' :
- case 'wrap' :
- $this->remove_column($table->$name, $target_col);
- break;
- case 'statheadercols' :
- $array = &$table->$name;
- $count = count($array);
- for ($i=0; $i<$count; $i++) {
- if ($array[$i]>=$target_col) {
- $array[$i] --;
- }
- }
- break;
- } // end switch
- } // end foreach
- } // end if
- } // end function
-
-/////////////////////////////////////////////////
-/// print a report in html, text or Excel format
-/////////////////////////////////////////////////
-
-// the stuff to print is contained in $table
-// which has the following properties:
-
-// $table->border border width for the table
-// $table->cellpadding padding on each cell
-// $table->cellspacing spacing between cells
-// $table->tableclass class for table
-// $table->width table width
-
-// $table->align is an array of column alignments
-// $table->class is an array of column classes
-// $table->size is an array of column sizes
-// $table->wrap is an array of column wrap/nowrap switches
-// $table->fontsize is an array of fontsizes
-
-// $table->caption is a caption (=title) for the report
-// $table->head is an array of headings (all TH cells)
-// $table->data[] is an array of arrays containing the data (all TD cells)
-// if a row is given as "hr", a "tabledivider" is inserted
-// if a cell is a string, it is assumed to be the cell content
-// a cell can also be an object, thus:
-// $cell->text : the content of the cell
-// $cell->rowspan : the row span of this cell
-// $cell->colspan : the column span of this cell
-// if rowspan or colspan are specified, neighboring cells are shifted accordingly
-// $table->stat[] is an array of arrays containing the statistics rows (TD and TH cells)
-// $table->foot[] is an array of arrays containing the footer rows (all TH cells)
-
-// $table->statheadercols is an array of column numbers which are headers
-
-
-//////////////////////////////////////////
-/// print a report
-
- function print_report(&$course, &$hotpot, &$tables, &$options) {
- switch ($options['reportformat']) {
- case 'txt':
- $this->print_text_report($course, $hotpot, $tables, $options);
- break;
- case 'xls':
- $this->print_excel_report($course, $hotpot, $tables, $options);
- break;
- default: // 'htm' (and anything else)
- $this->print_html_report($tables);
- break;
- }
- }
-
- function print_report_start(&$course, &$hotpot, &$options, &$table) {
- switch ($options['reportformat']) {
- case 'txt':
- $this->print_text_start($course, $hotpot, $options);
- break;
- case 'xls':
- $this->print_excel_start($course, $hotpot, $options);
- break;
-
- case 'htm':
- $this->print_html_start($course, $hotpot, $options);
- break;
- }
- }
-
- function print_report_cells(&$table, &$options, $zone) {
- switch ($options['reportformat']) {
- case 'txt':
- $fmt = 'text';
- break;
- case 'xls':
- $fmt = 'excel';
- break;
- default: // 'htm' (and anything else)
- $fmt = 'html';
- break;
- }
- $fn = "print_{$fmt}_{$zone}";
- $this->$fn($table, $options);
- }
-
- function print_report_finish(&$course, &$hotpot, &$options) {
- switch ($options['reportformat']) {
- case 'txt' :
- // do nothing
- break;
- case 'xls':
- $this->print_excel_finish($course, $hotpot, $options);
- break;
- case 'htm':
- $this->print_html_finish($course, $hotpot, $options);
- break;
- }
- }
-
-//////////////////////////////////////////
-/// print an html report
-
- function print_html_report(&$tables) {
- $count = count($tables);
- foreach($tables as $i=>$table) {
-
- $this->print_html_start($table);
- $this->print_html_head($table);
- $this->print_html_data($table);
- $this->print_html_stat($table);
- $this->print_html_foot($table);
- $this->print_html_finish($table);
-
- if (($i+1)<$count) {
- print_spacer(30, 10, true);
- }
- }
- }
- function print_html_start(&$table) {
-
- // default class for the table
- if (empty($table->tableclass)) {
- $table->tableclass = 'generaltable';
- }
-
- // default classes for TD and TH
- $d = $table->tableclass.'cell';
- $h = $table->tableclass.'header';
-
- $table->th_side = '<th valign="top" align="right" class="'.$h.'">';
-
- $table->td = array();
- $table->th_top = array();
-
- if (empty($table->colspan)) {
- if (isset($table->head)) {
- $table->colspan = count($table->head);
- } else if (isset($table->data)) {
- $table->colspan = count($table->data[0]);
- } else if (isset($table->stat)) {
- $table->colspan = count($table->stat);
- } else if (isset($table->foot)) {
- $table->colspan = count($table->foot);
- } else {
- $table->colspan = 0;
- }
- }
-
- for ($i=0; $i<$table->colspan; $i++) {
-
- $align = empty($table->align[$i]) ? '' : ' align="'.$table->align[$i].'"';
- $class = empty($table->class[$i]) ? $d : ' class="'.$table->class[$i].'"';
- $size = empty($table->size[$i]) ? '' : ' width="'.$table->size[$i].'"';
- $wrap = empty($table->wrap[$i]) ? '' : ' nowrap="nowrap"';
-
- $table->th_top[$i] = '<th align="center"'.$size.' class="'.$h.'" nowrap="nowrap">';
-
- $table->td[$i] = '<td valign="top"'.$align.$class.$wrap.'>';
-
- if (!empty($table->fontsize[$i])) {
- $table->td[$i] .= '<font size="'.$table->fontsize[$i].'">';
- }
- }
-
- if (empty($table->border)) {
- $table->border = 0;
- }
- if (empty($table->cellpadding)) {
- $table->cellpadding = 5;
- }
- if (empty($table->cellspacing)) {
- $table->cellspacing = 1;
- }
- if (empty($table->width)) {
- $table->width = "80%"; // actually the width of the "simple box"
- }
- if (empty($table->tablealign)) {
- $table->tablealign = "center";
- }
-
- if (isset($table->start)) {
- print $table->start."\n";
- }
-
- print_simple_box_start("$table->tablealign", "$table->width", "#ffffff", 0);
- print '<table width="100%" border="'.$table->border.'" valign="top" align="center" cellpadding="'.$table->cellpadding.'" cellspacing="'.$table->cellspacing.'" class="'.$table->tableclass.'">'."\n";
-
- if (isset($table->caption)) {
- print '<tr><td colspan="'.$table->colspan.'" class="'.$table->tableclass.'header"><b>'.$table->caption.'</b></td></tr>'."\n";
- }
-
- }
- function print_html_head(&$table) {
- if (isset($table->head)) {
- print "<tr>\n";
- foreach ($table->head as $i=>$cell) {
- $th = $table->th_top[$i];
- print $th.$cell."</th>\n";
- }
- print "</tr>\n";
- }
- }
- function print_html_data(&$table) {
- if (isset($table->data)) {
- $skipcol = array();
- foreach ($table->data as $cells) {
- print "<tr>\n";
- if (is_array($cells)) {
- $i = 0; // index on $cells
- $col = 0; // column index
- while ($col<$table->colspan && isset($cells[$i])) {
- if (empty($skipcol[$col])) {
- $cell = &$cells[$i++];
- $td = $table->td[$col];
- if (is_object($cell)) {
- $text = $cell->text;
- if (isset($cell->rowspan) && is_numeric($cell->rowspan) && ($cell->rowspan>0)) {
- $td = '<td rowspan="'.$cell->rowspan.'"'.substr($td, 3);
- // skip cells below this one
- $skipcol[$col] = $cell->rowspan-1;
- }
- if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>0)) {
- $td = '<td colspan="'.$cell->colspan.'"'.substr($td, 3);
- // skip cells to the right of this one
- for ($c=1; $c<$cell->colspan; $c++) {
- if (empty($skipcol[$col+$c])) {
- $skipcol[$col+$c] = 1;
- } else {
- $skipcol[$col+$c] ++;
- }
- }
- }
- } else { // $cell is a string
- $text = $cell;
- }
- print $td.$text."</td>\n";
- } else {
- $skipcol[$col]--;
- }
- $col++;
- } // end while
- } else if ($cells=='hr') {
- print '<td colspan="'.$table->colspan.'"><div class="tabledivider"></div></td>'."\n";
- }
- print "</tr>\n";
- }
- }
- }
- function print_html_stat(&$table) {
- if (isset($table->stat)) {
- if (empty($table->statheadercols)) {
- $table->statheadercols = array();
- }
- foreach ($table->stat as $cells) {
- print '<tr>';
- foreach ($cells as $i => $cell) {
- if (in_array($i, $table->statheadercols)) {
- $th = $table->th_side;
- print $th.$cell."</th>\n";
- } else {
- $td = $table->td[$i];
- print $td.$cell."</td>\n";
- }
- }
- print "</tr>\n";
- }
- }
- }
- function print_html_foot(&$table) {
- if (isset($table->foot)) {
- foreach ($table->foot as $cells) {
- print "<tr>\n";
- foreach ($cells as $i => $cell) {
- if ($i==0) {
- $th = $table->th_side;
- print $th.$cell."</th>\n";
- } else {
- $th = $table->th_top[$i];
- print $th.$cell."</th>\n";
- }
- }
- print "</tr>\n";
- }
- }
- }
- function print_html_finish(&$table) {
- print "</table>\n";
- print_simple_box_end();
-
- if (isset($table->finish)) {
- print $table->finish."\n";
- }
- }
-
-//////////////////////////////////////////
-/// print a text report
-
- function print_text_report(&$course, &$hotpot, &$tables, &$options) {
- $this->print_text_start($course, $hotpot, $options);
- foreach ($tables as $table) {
- $this->print_text_head($table, $options);
- $this->print_text_data($table, $options);
- $this->print_text_stat($table, $options);
- $this->print_text_foot($table, $options);
- }
- }
- function print_text_start(&$course, &$hotpot, &$options) {
- header("Content-Type: application/download\n");
- header("Content-Disposition: attachment; filename=$course->shortname-$hotpot->name.txt");
- header("Expires: 0");
- header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
- header("Pragma: public");
- }
- function print_text_head(&$table, &$options) {
- if (isset($table->caption)) {
- $i = strlen($table->caption);
- $data = array(
- array(str_repeat('=', $i)),
- array($table->caption),
- array(str_repeat('=', $i)),
- );
- foreach($data as $cells) {
- $this->print_text_cells($cells, $options);
- }
- }
- if (isset($table->head)) {
- $this->print_text_cells($table->head, $options);
- }
- }
- function print_text_data(&$table, &$options) {
- if (isset($table->data)) {
- foreach ($table->data as $cells) {
- $this->print_text_cells($cells, $options);
- }
- }
- }
- function print_text_stat(&$table, &$options) {
- if (isset($table->stat)) {
- foreach ($table->stat as $cells) {
- $this->print_text_cells($cells, $options);
- }
- }
- }
- function print_text_foot(&$table, &$options) {
- if (isset($table->foot)) {
- foreach ($table->foot as $cells) {
- $this->print_text_cells($cells, $options);
- }
- }
- }
- function print_text_cells(&$cells, &$options) {
-
- // do nothing if there are no cells
- if (empty($cells) || is_string($cells)) return;
-
- // convert to tab-delimted string
- $str = implode("\t", $cells);
-
- // replace newlines in string
- $str = preg_replace("/\n/", ",", $str);
-
- // set best newline for this browser (if it hasn't been done already)
- if (empty($this->nl)) {
- $s = &$_SERVER['HTTP_USER_AGENT'];
- $win = is_numeric(strpos($s, 'Win'));
- $mac = is_numeric(strpos($s, 'Mac')) && !is_numeric(strpos($s, 'OS X'));
- $this->nl = $win ? "\r\n" : ($mac ? "\r" : "\n");
- }
-
- print $str.$this->nl;
- }
-
-//////////////////////////////////////////
-/// print an Excel report
-
- function print_excel_report(&$course, &$hotpot, &$tables, &$options) {
- global $CFG;
- require_once("$CFG->libdir/excel/Worksheet.php");
- require_once("$CFG->libdir/excel/Workbook.php");
-
- // send headers to browser
- $this->print_excel_start($course, $hotpot, $options);
-
- // Create a new workbook
- $wb = new Workbook("-"); // $course->shortname
-
- foreach($tables as $table) {
- // create a worksheet for this table
- unset($ws);
- $ws = &$wb->add_worksheet(empty($table->caption) ? '' : strip_tags($table->caption));
-
- $row = 0;
- $this->print_excel_head($wb, $ws, $table, $row, $options);
- $this->print_excel_data($wb, $ws, $table, $row, $options);
- $this->print_excel_stat($wb, $ws, $table, $row, $options);
- $this->print_excel_foot($wb, $ws, $table, $row, $options);
- }
-
- // close the workbook (and send it to the browser)
- $wb->close();
- }
- function print_excel_start(&$course, &$hotpot, &$options) {
- header("Content-type: application/vnd.ms-excel");
- header("Content-Disposition: attachment; filename=$course->shortname $hotpot->name.xls" );
- header("Expires: 0");
- header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
- header("Pragma: public");
- }
- function print_excel_head(&$wb, &$ws, &$table, &$row, &$options) {
-
- // format properties
- $properties = array(
- 'bold'=>1,
- 'align'=>'center',
- 'valign'=>'bottom',
- 'text_wrap'=>1
- );
- // print the headings
- $this->print_excel_cells($wb, $ws, $table, $row, $properties, $table->head, $options);
- }
- function print_excel_data(&$wb, &$ws, &$table, &$row, &$options) {
-
- // do nothing if there are no cells
- if (empty($table->data)) return;
-
- // format properties
- $properties = array('text_wrap' => (empty($options['reportwrapdata']) ? 0 : 1));
-
- // print the data cells
- foreach ($table->data as $cells) {
- $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options);
- }
- }
- function print_excel_stat(&$wb, &$ws, &$table, &$row, &$options) {
-
- // do nothing if there are no cells
- if (empty($table->stat)) return;
-
- // format properties
- $properties = array('align'=>'right');
-
- $i_count = count($table->stat);
- foreach ($table->stat as $i => $cells) {
-
- // set border on top and bottom row
- $properties['top'] = ($i==0) ? 1 : 0;
- $properties['bottom'] = ($i==($i_count-1)) ? 1 : 0;
-
- // print this row of statistics
- $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options, $table->statheadercols);
- }
- }
- function print_excel_foot(&$wb, &$ws, &$table, &$row, &$options) {
-
- // do nothing if there are no cells
- if (empty($table->foot)) return;
-
- // format properties
- $properties = array('bold'=>1, 'align'=>'center');
-
- $i_count = count($table->foot);
- foreach ($table->foot as $i => $cells) {
-
- // set border on top and bottom row
- $properties['top'] = ($i==0) ? 1 : 0;
- $properties['bottom'] = ($i==($i_count-1)) ? 1 : 0;
-
- // print this footer row
- $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options);
- }
- }
-
- function print_excel_cells(&$wb, &$ws, &$table, &$row, &$properties, &$cells, &$options, $statheadercols=NULL) {
-
- // do nothing if there are no cells
- if (empty($cells) || is_string($cells)) return;
-
- foreach($cells as $col => $cell) {
-
- unset($fmt_properties);
- $fmt_properties = $properties;
-
- if (empty($fmt_properties['text_wrap'])) {
- if (strlen("$cell")>=9) {
- // long cell value
- $fmt_properties['align'] = 'left';
- }
- } else {
- if (strlen("$cell")<9 && strpos("$cell", "\n")===false) {
- // short cell value (wrapping not required)
- $fmt_properties['text_wrap'] = 0;
- }
- }
-
- // set bold, if required (for stat)
- if (isset($statheadercols)) {
- $fmt_properties['bold'] = in_array($col, $statheadercols) ? 1 : 0;
- $fmt_properties['align'] = in_array($col, $statheadercols) ? 'right' : $table->align[$col];
- }
-
- // set align, if required
- if (isset($table->align[$col]) && empty($fmt_properties['align'])) {
- $fmt_properties['align'] = $table->align[$col];
- }
-
- // check to see that an identical format object has not already been created
- unset($fmt);
- foreach ($wb->formats as $id=>$format) {
- if (isset($format->properties) && $format->properties==$fmt_properties) {
- $fmt = &$wb->formats[$id];
- break;
- }
- }
-
- // create new format object, if necessary (to avoid "too many cell formats" error)
- if (!isset($fmt)) {
- $fmt = &$wb->add_format($fmt_properties);
- $fmt->properties = &$fmt_properties;
-
- // set vertical alignment
- if (isset($fmt->properties['valign'])) {
- $fmt->set_align($fmt->properties['valign']);
- } else {
- $fmt->set_align('top'); // default
- }
- }
-
- // write cell
- if (is_numeric($cell) && !preg_match("/^0./", $cell)) {
- $ws->write_number($row, $col, $cell, $fmt);
- } else {
- if (!empty($options['reportencoding'])) {
- $in_charset = '';
- if (function_exists('mb_convert_encoding')) {
- $in_charset = mb_detect_encoding($cell, 'auto');
- }
- if (empty($in_charset)) {
- $in_charset = get_string('thischarset');
- }
- if ($in_charset != 'ASCII' && function_exists('mb_convert_encoding')) {
- $cell = mb_convert_encoding($cell, $options['reportencoding'], $in_charset);
- }
- }
- $ws->write_string($row, $col, $cell, $fmt);
- }
- } // end foreach $col
-
- // increment $row
- $row++;
- }
-}
-
-?>
+<?PHP // $Id$
+
+////////////////////////////////////////////////////////////////////
+/// Default class for report plugins
+///
+/// Doesn't do anything on it's own -- it needs to be extended.
+/// This class displays quiz reports. Because it is called from
+/// within /mod/quiz/report.php you can assume that the page header
+/// and footer are taken care of.
+///
+/// This file can refer to itself as report.php to pass variables
+/// to itself - all these will also be globally available. You must
+/// pass "id=$cm->id" or q=$quiz->id", and "mode=reportname".
+////////////////////////////////////////////////////////////////////
+
+// Included by ../report.php
+
+class hotpot_default_report {
+
+ function display($hotpot, $cm, $course, $users, $attempts, $questions, $options) {
+ /// This function just displays the report
+ // it is replaced by the "display" functions in the scripts in the "report" folder
+ return true;
+ }
+
+ function add_question_headings(&$questions, &$table, $align='center', $size=50, $wrap=false, $fontsize=0) {
+ $count = count($questions);
+ for ($i=0; $i<$count; $i++) {
+ $table->head[] = get_string('questionshort', 'hotpot', $i+1);
+ if (isset($table->align)) {
+ $table->align[] = $align;
+ }
+ if (isset($table->size)) {
+ $table->size[] = $size;
+ }
+ if (isset($table->wrap)) {
+ $table->wrap[] = $wrap;
+ }
+ if (isset($table->fontsize)) {
+ $table->fontsize[] = $fontsize;
+ }
+ }
+
+ }
+
+ function set_legend(&$table, &$q, &$value, &$question) {
+ // $q is the question number
+ // $value is the value (=text) of the answer
+
+ // check the legend is required
+ if (isset($table->legend) && isset($value)) {
+
+ // create question details array, if necessary
+ if (empty($table->legend[$q])) {
+ $table->legend[$q] = array(
+ 'name' => hotpot_get_question_name($question),
+ 'answers' => array()
+ );
+ }
+
+ // search for this $value in answers array for this $q(uestion)
+ $i_max = count($table->legend[$q]['answers']);
+ for ($i=0; $i<$i_max; $i++) {
+ if ($table->legend[$q]['answers'][$i]==$value) {
+ break;
+ }
+ }
+
+ // add $value to answers array, if it was not there
+ if ($i==$i_max) {
+ $table->legend[$q]['answers'][$i] = $value;
+ }
+
+ // convert $value to alphabetic index (A, B ... AA, AB ...)
+ $value = $this->dec_to_ALPHA($i);
+ }
+ }
+ function create_legend_table(&$tables, &$table) {
+
+ if (isset($table->legend)) {
+
+ $legend->width = '*';
+ $legend->tablealign = '*';
+ $legend->border = isset($table->border) ? $table->border : NULL;
+ $legend->cellpadding = isset($table->cellpadding) ? $table->cellpadding : NULL;
+ $legend->cellspacing = isset($table->cellspacing) ? $table->cellspacing : NULL;
+ $legend->tableclass = isset($table->tableclass) ? $table->tableclass : NULL;
+
+ $legend->caption = get_string('reportlegend', 'hotpot');
+ $legend->align = array('right', 'left');
+ $legend->statheadercols = array(0);
+
+ $legend->stat = array();
+
+ // put the questions in order
+ sort($table->legend);
+
+ foreach($table->legend as $q=>$question) {
+
+ $legend->stat[] = array(
+ get_string('questionshort', 'hotpot', $q+1),
+ $question['name']
+ );
+ foreach($question['answers'] as $a=>$answer) {
+ $legend->stat[] = array(
+ $this->dec_to_ALPHA($a),
+ $answer
+ );
+ }
+ }
+
+ unset($table->legend);
+ $tables[] = $legend;
+ }
+ }
+ function dec_to_ALPHA($dec) {
+ if ($dec < 26) {
+ return chr(ord('A') + $dec);
+ } else {
+ return $this->dec_to_ALPHA(intval($dec/26)-1).$this->dec_to_ALPHA($dec % 26);
+ }
+ }
+ function remove_column(&$table, $target_col) {
+
+ if (is_array($table)) {
+ unset($table[$target_col]);
+ $table = array_values($table);
+
+ } else if (is_object($table)) {
+ $vars = get_object_vars($table);
+ foreach ($vars as $name=>$value) {
+ switch ($name) {
+ case 'data' :
+ case 'stat' :
+ case 'foot' :
+ $skipcol = array();
+ $cells = &$table->$name;
+
+ $row_max = count($cells);
+ for ($row=0; $row<$row_max; $row++) {
+
+ $col = 0;
+ $col_max = count($cells[$row]);
+
+ $current_col = 0;
+ while ($current_col<$target_col && $col<$col_max) {
+
+ if (empty($skipcol[$current_col])) {
+
+ $cell = $cells[$row][$col++];
+ if (is_object($cell)) {
+ if (isset($cell->rowspan) && is_numeric($cell->rowspan) && ($cell->rowspan>0)) {
+ // skip cells below this one
+ $skipcol[$current_col] = $cell->rowspan-1;
+ }
+ if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>0)) {
+ // skip cells to the right of this one
+ for ($c=1; $c<$cell->colspan; $c++) {
+ if (empty($skipcol[$current_col+$c])) {
+ $skipcol[$current_col+$c] = 1;
+ } else {
+ $skipcol[$current_col+$c] ++;
+ }
+ }
+ }
+ }
+ } else {
+ $skipcol[$current_col]--;
+ }
+ $current_col++;
+ }
+ if ($current_col==$target_col && $col<$col_max) {
+ $this->remove_column($cells[$row], $col);
+ }
+ } // end for $row
+ break;
+ case 'head' :
+ case 'align' :
+ case 'class' :
+ case 'fontsize' :
+ case 'size' :
+ case 'wrap' :
+ $this->remove_column($table->$name, $target_col);
+ break;
+ case 'statheadercols' :
+ $array = &$table->$name;
+ $count = count($array);
+ for ($i=0; $i<$count; $i++) {
+ if ($array[$i]>=$target_col) {
+ $array[$i] --;
+ }
+ }
+ break;
+ } // end switch
+ } // end foreach
+ } // end if
+ } // end function
+
+/////////////////////////////////////////////////
+/// print a report in html, text or Excel format
+/////////////////////////////////////////////////
+
+// the stuff to print is contained in $table
+// which has the following properties:
+
+// $table->border border width for the table
+// $table->cellpadding padding on each cell
+// $table->cellspacing spacing between cells
+// $table->tableclass class for table
+// $table->width table width
+
+// $table->align is an array of column alignments
+// $table->class is an array of column classes
+// $table->size is an array of column sizes
+// $table->wrap is an array of column wrap/nowrap switches
+// $table->fontsize is an array of fontsizes
+
+// $table->caption is a caption (=title) for the report
+// $table->head is an array of headings (all TH cells)
+// $table->data[] is an array of arrays containing the data (all TD cells)
+// if a row is given as "hr", a "tabledivider" is inserted
+// if a cell is a string, it is assumed to be the cell content
+// a cell can also be an object, thus:
+// $cell->text : the content of the cell
+// $cell->rowspan : the row span of this cell
+// $cell->colspan : the column span of this cell
+// if rowspan or colspan are specified, neighboring cells are shifted accordingly
+// $table->stat[] is an array of arrays containing the statistics rows (TD and TH cells)
+// $table->foot[] is an array of arrays containing the footer rows (all TH cells)
+
+// $table->statheadercols is an array of column numbers which are headers
+
+
+//////////////////////////////////////////
+/// print a report
+
+ function print_report(&$course, &$hotpot, &$tables, &$options) {
+ switch ($options['reportformat']) {
+ case 'txt':
+ $this->print_text_report($course, $hotpot, $tables, $options);
+ break;
+ case 'xls':
+ $this->print_excel_report($course, $hotpot, $tables, $options);
+ break;
+ default: // 'htm' (and anything else)
+ $this->print_html_report($tables);
+ break;
+ }
+ }
+
+ function print_report_start(&$course, &$hotpot, &$options, &$table) {
+ switch ($options['reportformat']) {
+ case 'txt':
+ $this->print_text_start($course, $hotpot, $options);
+ break;
+ case 'xls':
+ $this->print_excel_start($course, $hotpot, $options);
+ break;
+
+ case 'htm':
+ $this->print_html_start($course, $hotpot, $options);
+ break;
+ }
+ }
+
+ function print_report_cells(&$table, &$options, $zone) {
+ switch ($options['reportformat']) {
+ case 'txt':
+ $fmt = 'text';
+ break;
+ case 'xls':
+ $fmt = 'excel';
+ break;
+ default: // 'htm' (and anything else)
+ $fmt = 'html';
+ break;
+ }
+ $fn = "print_{$fmt}_{$zone}";
+ $this->$fn($table, $options);
+ }
+
+ function print_report_finish(&$course, &$hotpot, &$options) {
+ switch ($options['reportformat']) {
+ case 'txt' :
+ // do nothing
+ break;
+ case 'xls':
+ $this->print_excel_finish($course, $hotpot, $options);
+ break;
+ case 'htm':
+ $this->print_html_finish($course, $hotpot, $options);
+ break;
+ }
+ }
+
+//////////////////////////////////////////
+/// print an html report
+
+ function print_html_report(&$tables) {
+ $count = count($tables);
+ foreach($tables as $i=>$table) {
+
+ $this->print_html_start($table);
+ $this->print_html_head($table);
+ $this->print_html_data($table);
+ $this->print_html_stat($table);
+ $this->print_html_foot($table);
+ $this->print_html_finish($table);
+
+ if (($i+1)<$count) {
+ print_spacer(30, 10, true);
+ }
+ }
+ }
+ function print_html_start(&$table) {
+
+ // default class for the table
+ if (empty($table->tableclass)) {
+ $table->tableclass = 'generaltable';
+ }
+
+ // default classes for TD and TH
+ $d = $table->tableclass.'cell';
+ $h = $table->tableclass.'header';
+
+ $table->th_side = '<th valign="top" align="right" class="'.$h.'">';
+
+ $table->td = array();
+ $table->th_top = array();
+
+ if (empty($table->colspan)) {
+ if (isset($table->head)) {
+ $table->colspan = count($table->head);
+ } else if (isset($table->data)) {
+ $table->colspan = count($table->data[0]);
+ } else if (isset($table->stat)) {
+ $table->colspan = count($table->stat);
+ } else if (isset($table->foot)) {
+ $table->colspan = count($table->foot);
+ } else {
+ $table->colspan = 0;
+ }
+ }
+
+ for ($i=0; $i<$table->colspan; $i++) {
+
+ $align = empty($table->align[$i]) ? '' : ' align="'.$table->align[$i].'"';
+ $class = empty($table->class[$i]) ? $d : ' class="'.$table->class[$i].'"';
+ $size = empty($table->size[$i]) ? '' : ' width="'.$table->size[$i].'"';
+ $wrap = empty($table->wrap[$i]) ? '' : ' nowrap="nowrap"';
+
+ $table->th_top[$i] = '<th align="center"'.$size.' class="'.$h.'" nowrap="nowrap">';
+
+ $table->td[$i] = '<td valign="top"'.$align.$class.$wrap.'>';
+
+ if (!empty($table->fontsize[$i])) {
+ $table->td[$i] .= '<font size="'.$table->fontsize[$i].'">';
+ }
+ }
+
+ if (empty($table->border)) {
+ $table->border = 0;
+ }
+ if (empty($table->cellpadding)) {
+ $table->cellpadding = 5;
+ }
+ if (empty($table->cellspacing)) {
+ $table->cellspacing = 1;
+ }
+ if (empty($table->width)) {
+ $table->width = "80%"; // actually the width of the "simple box"
+ }
+ if (empty($table->tablealign)) {
+ $table->tablealign = "center";
+ }
+
+ if (isset($table->start)) {
+ print $table->start."\n";
+ }
+
+ print_simple_box_start("$table->tablealign", "$table->width", "#ffffff", 0);
+ print '<table width="100%" border="'.$table->border.'" valign="top" align="center" cellpadding="'.$table->cellpadding.'" cellspacing="'.$table->cellspacing.'" class="'.$table->tableclass.'">'."\n";
+
+ if (isset($table->caption)) {
+ print '<tr><td colspan="'.$table->colspan.'" class="'.$table->tableclass.'header"><b>'.$table->caption.'</b></td></tr>'."\n";
+ }
+
+ }
+ function print_html_head(&$table) {
+ if (isset($table->head)) {
+ print "<tr>\n";
+ foreach ($table->head as $i=>$cell) {
+ $th = $table->th_top[$i];
+ print $th.$cell."</th>\n";
+ }
+ print "</tr>\n";
+ }
+ }
+ function print_html_data(&$table) {
+ if (isset($table->data)) {
+ $skipcol = array();
+ foreach ($table->data as $cells) {
+ print "<tr>\n";
+ if (is_array($cells)) {
+ $i = 0; // index on $cells
+ $col = 0; // column index
+ while ($col<$table->colspan && isset($cells[$i])) {
+ if (empty($skipcol[$col])) {
+ $cell = &$cells[$i++];
+ $td = $table->td[$col];
+ if (is_object($cell)) {
+ $text = $cell->text;
+ if (isset($cell->rowspan) && is_numeric($cell->rowspan) && ($cell->rowspan>0)) {
+ $td = '<td rowspan="'.$cell->rowspan.'"'.substr($td, 3);
+ // skip cells below this one
+ $skipcol[$col] = $cell->rowspan-1;
+ }
+ if (isset($cell->colspan) && is_numeric($cell->colspan) && ($cell->colspan>0)) {
+ $td = '<td colspan="'.$cell->colspan.'"'.substr($td, 3);
+ // skip cells to the right of this one
+ for ($c=1; $c<$cell->colspan; $c++) {
+ if (empty($skipcol[$col+$c])) {
+ $skipcol[$col+$c] = 1;
+ } else {
+ $skipcol[$col+$c] ++;
+ }
+ }
+ }
+ } else { // $cell is a string
+ $text = $cell;
+ }
+ print $td.$text."</td>\n";
+ } else {
+ $skipcol[$col]--;
+ }
+ $col++;
+ } // end while
+ } else if ($cells=='hr') {
+ print '<td colspan="'.$table->colspan.'"><div class="tabledivider"></div></td>'."\n";
+ }
+ print "</tr>\n";
+ }
+ }
+ }
+ function print_html_stat(&$table) {
+ if (isset($table->stat)) {
+ if (empty($table->statheadercols)) {
+ $table->statheadercols = array();
+ }
+ foreach ($table->stat as $cells) {
+ print '<tr>';
+ foreach ($cells as $i => $cell) {
+ if (in_array($i, $table->statheadercols)) {
+ $th = $table->th_side;
+ print $th.$cell."</th>\n";
+ } else {
+ $td = $table->td[$i];
+ print $td.$cell."</td>\n";
+ }
+ }
+ print "</tr>\n";
+ }
+ }
+ }
+ function print_html_foot(&$table) {
+ if (isset($table->foot)) {
+ foreach ($table->foot as $cells) {
+ print "<tr>\n";
+ foreach ($cells as $i => $cell) {
+ if ($i==0) {
+ $th = $table->th_side;
+ print $th.$cell."</th>\n";
+ } else {
+ $th = $table->th_top[$i];
+ print $th.$cell."</th>\n";
+ }
+ }
+ print "</tr>\n";
+ }
+ }
+ }
+ function print_html_finish(&$table) {
+ print "</table>\n";
+ print_simple_box_end();
+
+ if (isset($table->finish)) {
+ print $table->finish."\n";
+ }
+ }
+
+//////////////////////////////////////////
+/// print a text report
+
+ function print_text_report(&$course, &$hotpot, &$tables, &$options) {
+ $this->print_text_start($course, $hotpot, $options);
+ foreach ($tables as $table) {
+ $this->print_text_head($table, $options);
+ $this->print_text_data($table, $options);
+ $this->print_text_stat($table, $options);
+ $this->print_text_foot($table, $options);
+ }
+ }
+ function print_text_start(&$course, &$hotpot, &$options) {
+ header("Content-Type: application/download\n");
+ header("Content-Disposition: attachment; filename=$course->shortname-$hotpot->name.txt");
+ header("Expires: 0");
+ header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
+ header("Pragma: public");
+ }
+ function print_text_head(&$table, &$options) {
+ if (isset($table->caption)) {
+ $i = strlen($table->caption);
+ $data = array(
+ array(str_repeat('=', $i)),
+ array($table->caption),
+ array(str_repeat('=', $i)),
+ );
+ foreach($data as $cells) {
+ $this->print_text_cells($cells, $options);
+ }
+ }
+ if (isset($table->head)) {
+ $this->print_text_cells($table->head, $options);
+ }
+ }
+ function print_text_data(&$table, &$options) {
+ if (isset($table->data)) {
+ foreach ($table->data as $cells) {
+ $this->print_text_cells($cells, $options);
+ }
+ }
+ }
+ function print_text_stat(&$table, &$options) {
+ if (isset($table->stat)) {
+ foreach ($table->stat as $cells) {
+ $this->print_text_cells($cells, $options);
+ }
+ }
+ }
+ function print_text_foot(&$table, &$options) {
+ if (isset($table->foot)) {
+ foreach ($table->foot as $cells) {
+ $this->print_text_cells($cells, $options);
+ }
+ }
+ }
+ function print_text_cells(&$cells, &$options) {
+
+ // do nothing if there are no cells
+ if (empty($cells) || is_string($cells)) return;
+
+ // convert to tab-delimted string
+ $str = implode("\t", $cells);
+
+ // replace newlines in string
+ $str = preg_replace("/\n/", ",", $str);
+
+ // set best newline for this browser (if it hasn't been done already)
+ if (empty($this->nl)) {
+ $s = &$_SERVER['HTTP_USER_AGENT'];
+ $win = is_numeric(strpos($s, 'Win'));
+ $mac = is_numeric(strpos($s, 'Mac')) && !is_numeric(strpos($s, 'OS X'));
+ $this->nl = $win ? "\r\n" : ($mac ? "\r" : "\n");
+ }
+
+ print $str.$this->nl;
+ }
+
+//////////////////////////////////////////
+/// print an Excel report
+
+ function print_excel_report(&$course, &$hotpot, &$tables, &$options) {
+ global $CFG;
+ require_once("$CFG->libdir/excel/Worksheet.php");
+ require_once("$CFG->libdir/excel/Workbook.php");
+
+ // send headers to browser
+ $this->print_excel_start($course, $hotpot, $options);
+
+ // Create a new workbook
+ $wb = new Workbook("-"); // $course->shortname
+
+ foreach($tables as $table) {
+ // create a worksheet for this table
+ unset($ws);
+ $ws = &$wb->add_worksheet(empty($table->caption) ? '' : strip_tags($table->caption));
+
+ $row = 0;
+ $this->print_excel_head($wb, $ws, $table, $row, $options);
+ $this->print_excel_data($wb, $ws, $table, $row, $options);
+ $this->print_excel_stat($wb, $ws, $table, $row, $options);
+ $this->print_excel_foot($wb, $ws, $table, $row, $options);
+ }
+
+ // close the workbook (and send it to the browser)
+ $wb->close();
+ }
+ function print_excel_start(&$course, &$hotpot, &$options) {
+ header("Content-type: application/vnd.ms-excel");
+ header("Content-Disposition: attachment; filename=$course->shortname $hotpot->name.xls" );
+ header("Expires: 0");
+ header("Cache-Control: must-revalidate, post-check=0,pre-check=0");
+ header("Pragma: public");
+ }
+ function print_excel_head(&$wb, &$ws, &$table, &$row, &$options) {
+
+ // format properties
+ $properties = array(
+ 'bold'=>1,
+ 'align'=>'center',
+ 'valign'=>'bottom',
+ 'text_wrap'=>1
+ );
+ // print the headings
+ $this->print_excel_cells($wb, $ws, $table, $row, $properties, $table->head, $options);
+ }
+ function print_excel_data(&$wb, &$ws, &$table, &$row, &$options) {
+
+ // do nothing if there are no cells
+ if (empty($table->data)) return;
+
+ // format properties
+ $properties = array('text_wrap' => (empty($options['reportwrapdata']) ? 0 : 1));
+
+ // print the data cells
+ foreach ($table->data as $cells) {
+ $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options);
+ }
+ }
+ function print_excel_stat(&$wb, &$ws, &$table, &$row, &$options) {
+
+ // do nothing if there are no cells
+ if (empty($table->stat)) return;
+
+ // format properties
+ $properties = array('align'=>'right');
+
+ $i_count = count($table->stat);
+ foreach ($table->stat as $i => $cells) {
+
+ // set border on top and bottom row
+ $properties['top'] = ($i==0) ? 1 : 0;
+ $properties['bottom'] = ($i==($i_count-1)) ? 1 : 0;
+
+ // print this row of statistics
+ $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options, $table->statheadercols);
+ }
+ }
+ function print_excel_foot(&$wb, &$ws, &$table, &$row, &$options) {
+
+ // do nothing if there are no cells
+ if (empty($table->foot)) return;
+
+ // format properties
+ $properties = array('bold'=>1, 'align'=>'center');
+
+ $i_count = count($table->foot);
+ foreach ($table->foot as $i => $cells) {
+
+ // set border on top and bottom row
+ $properties['top'] = ($i==0) ? 1 : 0;
+ $properties['bottom'] = ($i==($i_count-1)) ? 1 : 0;
+
+ // print this footer row
+ $this->print_excel_cells($wb, $ws, $table, $row, $properties, $cells, $options);
+ }
+ }
+
+ function print_excel_cells(&$wb, &$ws, &$table, &$row, &$properties, &$cells, &$options, $statheadercols=NULL) {
+
+ // do nothing if there are no cells
+ if (empty($cells) || is_string($cells)) return;
+
+ foreach($cells as $col => $cell) {
+
+ unset($fmt_properties);
+ $fmt_properties = $properties;
+
+ if (empty($fmt_properties['text_wrap'])) {
+ if (strlen("$cell")>=9) {
+ // long cell value
+ $fmt_properties['align'] = 'left';
+ }
+ } else {
+ if (strlen("$cell")<9 && strpos("$cell", "\n")===false) {
+ // short cell value (wrapping not required)
+ $fmt_properties['text_wrap'] = 0;
+ }
+ }
+
+ // set bold, if required (for stat)
+ if (isset($statheadercols)) {
+ $fmt_properties['bold'] = in_array($col, $statheadercols) ? 1 : 0;
+ $fmt_properties['align'] = in_array($col, $statheadercols) ? 'right' : $table->align[$col];
+ }
+
+ // set align, if required
+ if (isset($table->align[$col]) && empty($fmt_properties['align'])) {
+ $fmt_properties['align'] = $table->align[$col];
+ }
+
+ // check to see that an identical format object has not already been created
+ unset($fmt);
+ foreach ($wb->formats as $id=>$format) {
+ if (isset($format->properties) && $format->properties==$fmt_properties) {
+ $fmt = &$wb->formats[$id];
+ break;
+ }
+ }
+
+ // create new format object, if necessary (to avoid "too many cell formats" error)
+ if (!isset($fmt)) {
+ $fmt = &$wb->add_format($fmt_properties);
+ $fmt->properties = &$fmt_properties;
+
+ // set vertical alignment
+ if (isset($fmt->properties['valign'])) {
+ $fmt->set_align($fmt->properties['valign']);
+ } else {
+ $fmt->set_align('top'); // default
+ }
+ }
+
+ // write cell
+ if (is_numeric($cell) && !preg_match("/^0./", $cell)) {
+ $ws->write_number($row, $col, $cell, $fmt);
+ } else {
+ if (!empty($options['reportencoding'])) {
+ $in_charset = '';
+ if (function_exists('mb_convert_encoding')) {
+ $in_charset = mb_detect_encoding($cell, 'auto');
+ }
+ if (empty($in_charset)) {
+ $in_charset = get_string('thischarset');
+ }
+ if ($in_charset != 'ASCII' && function_exists('mb_convert_encoding')) {
+ $cell = mb_convert_encoding($cell, $options['reportencoding'], $in_charset);
+ }
+ }
+ $ws->write_string($row, $col, $cell, $fmt);
+ }
+ } // end foreach $col
+
+ // increment $row
+ $row++;
+ }
+}
+
+?>

0 comments on commit d4817b7

Please sign in to comment.