[ Index ]

PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008]

title

Body

[close]

/mod/hotpot/report/fullstat/ -> report.php (source)

   1  <?php  // $Id: report.php,v 1.7.4.3 2008/03/06 07:34:04 gbateson Exp $
   2  /// Overview report just displays a big table of all the attempts
   3  class hotpot_report extends hotpot_default_report {
   4  	function display(&$hotpot, &$cm, &$course, &$users, &$attempts, &$questions, &$options) {
   5          global $CFG;
   6          // create the tables
   7          $tables = array();
   8          $this->create_responses_table($hotpot, $course, $users, $attempts, $questions, $options, $tables);
   9          $this->create_analysis_table($users, $attempts, $questions, $options, $tables);
  10          // print report
  11          $this->print_report($course, $hotpot, $tables, $options);
  12          return true;
  13      }
  14  	function create_responses_table(&$hotpot, &$course, &$users, &$attempts, &$questions, &$options, &$tables) {
  15          global $CFG;
  16          $is_html = ($options['reportformat']=='htm');
  17          // shortcuts for font tags
  18          $br = $is_html ? "<br />\n" : "\n";
  19          $blank = $is_html ? '&nbsp;' : "";
  20          $font_end   = $is_html ? '</font>' : '';
  21          $font_red   = $is_html ? '<font color="red">'   : '';
  22          $font_blue  = $is_html ? '<font color="blue">'  : '';
  23          $font_brown = $is_html ? '<font color="brown">' : '';
  24          $font_green = $is_html ? '<font color="green">' : '';
  25          $font_small = $is_html ? '<font size="-2">' : '';
  26          $nobr_start = $is_html ? '<nobr>'  : '';
  27          $nobr_end   = $is_html ? '</nobr>' : '';
  28          // is review allowed? (do this once here, to save time later)
  29          $allow_review = ($is_html && (has_capability('mod/hotpot:viewreport',get_context_instance(CONTEXT_COURSE, $course->id)) || $hotpot->review));
  30          // assume penalties column is NOT required
  31          $show_penalties = false;
  32          // initialize $table
  33          unset($table);
  34          $table->border = 1;
  35          $table->width = '100%';
  36          // initialize legend, if necessary
  37          if (!empty($options['reportshowlegend'])) {
  38              $table->legend = array();
  39          }
  40          // headings for name, attempt number, score/grade and penalties
  41          $table->head = array(
  42              get_string("name"),
  43              hotpot_grade_heading($hotpot, $options),
  44              get_string('attempt', 'quiz'),
  45          );
  46          $table->align = array('left', 'center', 'center');
  47          $table->size = array(150, 80, 10);
  48          $table->wrap = array(0, 0, 0);
  49          $table->fontsize = array(0, 0, 0);
  50          // question headings
  51          $this->add_question_headings($questions, $table, 'left', 0, false, 2);
  52          // penalties (not always needed) and raw score
  53          array_push($table->head,
  54              get_string('penalties', 'hotpot'),
  55              get_string('score', 'quiz')
  56          );
  57          array_push($table->align, 'center', 'center');
  58          array_push($table->size, 50, 50);
  59          array_push($table->wrap, 0, 0);
  60          array_push($table->fontsize, 0, 0);
  61          // message strings
  62          $strnoresponse = get_string('noresponse', 'quiz');
  63          // array to map columns onto question ids ($col => $id)
  64          $questionids = array_keys($questions);
  65          // add details of users' responses
  66          foreach ($users as $user) {
  67              // shortcut to user info held in first attempt record
  68              $u = &$user->attempts[0];
  69              if (function_exists("fullname")) {
  70                  $name = fullname($u);
  71              } else {
  72                  $name = "$u->firstname $u->lastname";
  73              }
  74              if ($is_html) {
  75                  $name = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$u->userid.'&amp;course='.$course->id.'">'.$name.'</a>';
  76              }
  77              $grade = isset($user->grade) ? $user->grade : $blank;
  78              foreach ($user->attempts as $attempt) {
  79                  $attemptnumber = $attempt->attempt;
  80                  if ($allow_review) {
  81                      $attemptnumber = ' <a href="review.php?hp='.$hotpot->id.'&amp;attempt='.$attempt->id.'">'.$attemptnumber.'</a>';
  82                  }
  83                  $cells = array ($name, $grade, $attemptnumber);
  84                  // $name and $grade are only printed on first line per user
  85                  $name = $blank;
  86                  $grade = $blank;
  87                  $start_col = count($cells);
  88                  foreach ($questionids as $col => $id) {
  89                      $cells[$start_col + $col] = "$font_brown($strnoresponse)$font_end";
  90                  }
  91                  if (isset($attempt->penalties)) {
  92                      $show_penalties = true;
  93                      $penalties = $attempt->penalties;
  94                  } else {
  95                      $penalties = $blank;
  96                  }
  97                  array_push($cells, $penalties, hotpot_format_score($attempt));
  98                  // get responses to questions in this attempt
  99                  foreach ($attempt->responses as $response) {
 100                      // check this question id is OK (should be)
 101                      $col = array_search($response->question, $questionids);
 102                      if (is_numeric($col)) {
 103                          // correct
 104                          if ($value = hotpot_strings($response->correct)) {
 105                              $this->set_legend($table, $col, $value, $questions[$response->question]);
 106                          } else {
 107                              $value = "($strnoresponse)";
 108                          }
 109                          $cell = $font_red.$value.$font_end;
 110                          // wrong
 111                          if ($value = hotpot_strings($response->wrong)) {
 112                              if (isset($table->legend)) {
 113                                  $values = array();
 114                                  foreach (explode(',', $value) as $v) {
 115                                      $this->set_legend($table, $col, $v, $questions[$response->question]);
 116                                      $values[] = $v;
 117                                  }
 118                                  $value = implode(',', $values);
 119                              }
 120                              $cell .= $br.$font_blue.$value.$font_end;
 121                          }
 122                          // ignored
 123                          if ($value = hotpot_strings($response->ignored)) {
 124                              if (isset($table->legend)) {
 125                                  $values = array();
 126                                  foreach (explode(',', $value) as $v) {
 127                                      $this->set_legend($table, $col, $v, $questions[$response->question]);
 128                                      $values[] = $v;
 129                                  }
 130                                  $value = implode(',', $values);
 131                              }
 132                              $cell .= $br.$font_brown.$value.$font_end;
 133                          }
 134                          // numeric
 135                          if (is_numeric($response->score)) {
 136                              if (empty($table->caption)) {
 137                                  $table->caption = get_string('indivresp', 'quiz');
 138                                  if ($is_html) {
 139                                      $table->caption .= helpbutton('responsestable', $table->caption, 'hotpot', true, false, '', true);
 140                                  }
 141                              }
 142                              $hints = empty($response->hints) ? 0 : $response->hints;
 143                              $clues = empty($response->clues) ? 0 : $response->clues;
 144                              $checks = empty($response->checks) ? 0 : $response->checks;
 145                              $numeric = $response->score.'% '.$blank.' ('.$hints.','.$clues.','.$checks.')';
 146                              $cell .= $br.$nobr_start.$font_green.$numeric.$font_end.$nobr_end;
 147                          }
 148                          $cells[$start_col + $col] = $cell;
 149                      }
 150                  }
 151                  $table->data[] = $cells;
 152              }
 153              // insert 'tabledivider' between users
 154              $table->data[] = 'hr';
 155          } // end foreach $users
 156          // remove final 'hr' from data rows
 157          array_pop($table->data);
 158          if (!$show_penalties) {
 159              $col = 3 + count($questionids);
 160              $this->remove_column($table, $col);
 161          }
 162          $tables[] = &$table;
 163      }
 164  	function create_analysis_table(&$users, &$attempts, &$questions, &$options, &$tables) {
 165          $is_html = ($options['reportformat']=='htm');
 166          // the fields we are interested in, in the order we want them
 167          $fields = array('correct', 'wrong', 'ignored', 'hints', 'clues', 'checks', 'weighting');
 168          $string_fields = array('correct', 'wrong', 'ignored');
 169          $q = array(); // statistics about the $q(uestions)
 170          $f = array(); // statistics about the $f(ields)
 171          ////////////////////////////////////////////
 172          // compile the statistics about the questions
 173          ////////////////////////////////////////////
 174          foreach ($questions as $id=>$question) {
 175              // extract scores for attempts at this question
 176              $scores = array();
 177              foreach ($question->attempts as $attempt) {
 178                  $scores[] = $attempt->score;
 179              }
 180              // sort scores values (in ascending order)
 181              asort($scores);
 182              // get the borderline high and low scores
 183              $count = count($scores);
 184              switch ($count) {
 185                  case 0:
 186                      $lo_score = 0;
 187                      $hi_score = 0;
 188                      break;
 189                  case 1:
 190                      $lo_score = 0;
 191                      $hi_score = $scores[0];
 192                      break;
 193                  default:
 194                      $lo_score = $scores[round($count*1/3)];
 195                      $hi_score = $scores[round($count*2/3)];
 196                      break;
 197              }
 198              // get statistics for each attempt which includes this question
 199              foreach ($question->attempts as $attempt) {
 200                  $is_hi_score = ($attempt->score >= $hi_score);
 201                  $is_lo_score = ($attempt->score <  $lo_score);
 202                  // reference to the response to the current question
 203                  $response = &$attempt->responses[$id];
 204                  // update statistics for fields in this response
 205                  foreach($fields as $field) {
 206                      if (!isset($q[$id])) {
 207                          $q[$id] = array();
 208                      }
 209                      if (!isset($f[$field])) {
 210                          $f[$field] = array('count' => 0);
 211                      }
 212                      if (!isset($q[$id][$field])) {
 213                          $q[$id][$field] = array('count' => 0);
 214                      }
 215                      $values = explode(',', $response->$field);
 216                      $values = array_unique($values);
 217                      foreach($values as $value) {
 218                          // $value should be an integer (string_id or count)
 219                          if (is_numeric($value)) {
 220                              $f[$field]['count']++;
 221                              if (!isset($q[$id][$field][$value])) {
 222                                  $q[$id][$field][$value] = 0;
 223                              }
 224                              $q[$id][$field]['count']++;
 225                              $q[$id][$field][$value]++;
 226                          }
 227                      }
 228                  } // end foreach $field
 229                  // initialize counters for this question, if necessary
 230                  if (!isset($q[$id]['count'])) {
 231                      $q[$id]['count'] = array('hi'=>0, 'lo'=>0, 'correct'=>0, 'total'=>0, 'sum'=>0);
 232                  }
 233                  // increment counters
 234                  $q[$id]['count']['sum'] += $response->score;
 235                  $q[$id]['count']['total']++;
 236                  if ($response->score==100) {
 237                      $q[$id]['count']['correct']++;
 238                      if ($is_hi_score) {
 239                          $q[$id]['count']['hi']++;
 240                      } else if ($is_lo_score) {
 241                          $q[$id]['count']['lo']++;
 242                      }
 243                  }
 244              } // end foreach attempt
 245          } // end foreach question
 246          // check we have some details
 247          if (count($q)) {
 248              $showhideid = 'showhide';
 249              // shortcuts for html tags
 250              $bold_start = $is_html ? '<strong>' :  "";
 251              $bold_end = $is_html ? '</strong>' : "";
 252              $div_start = $is_html ? '<div id="'.$showhideid.'">' : "";
 253              $div_end = $is_html ? '</div>' : "";
 254              $font_red   = $is_html ? '<font color="red" size="-2">' : '';
 255              $font_blue  = $is_html ? '<font color="blue" size="-2">' : '';
 256              $font_green = $is_html ? '<font color="green" size="-2">' : '';
 257              $font_brown = $is_html ? '<font color="brown" size="-2">' : '';
 258              $font_end = $is_html ? '</font>'."\n" : '';
 259              $br = $is_html ? '<br />' : "\n";
 260              $space = $is_html ? '&nbsp;' : "";
 261              $no_value = $is_html ? '--' : "";
 262              $help_button = $is_html ? helpbutton("discrimination", get_string('discrimination', 'quiz'), "quiz", true, false, "", true) : "";
 263              // table properties
 264              unset($table);
 265              $table->border = 1;
 266              $table->width = '100%';
 267              $table->caption = get_string('itemanal', 'quiz');
 268              if ($is_html) {
 269                  $table->caption .= helpbutton('analysistable', $table->caption, 'hotpot', true, false, '', true);
 270              }
 271              // initialize legend, if necessary
 272              if (!empty($options['reportshowlegend'])) {
 273                  if (empty($tables) || empty($tables[0]->legend)) {
 274                      $table->legend = array();
 275                  } else {
 276                      $table->legend = $tables[0]->legend;
 277                      unset($tables[0]->legend);
 278                  }
 279              }
 280              // headings for name, attempt number and score/grade
 281              $table->head = array($space);
 282              $table->align = array('right');
 283              $table->size = array(80);
 284              // question headings
 285              $this->add_question_headings($questions, $table, 'left', 0);
 286              // initialize statistics
 287              $table->stat = array();
 288              $table->statheadercols = array(0);
 289              // add headings for the $foot of the $table
 290              $table->foot = array();
 291              $table->foot[0] = array(get_string('average', 'hotpot'));
 292              $table->foot[1] = array(get_string('percentcorrect', 'quiz'));
 293              $table->foot[2] = array(get_string('discrimination', 'quiz').$help_button);
 294              // maximum discrimination index (also default the default value)
 295              $max_d_index = 10;
 296              ////////////////////////////////////////////
 297              // format the statistics into the $table
 298              ////////////////////////////////////////////
 299              // add $stat(istics) and $foot of $table
 300              $questionids = array_keys($q);
 301              foreach ($questionids as $col => $id) {
 302                  $row = 0;
 303                  // print the question text if there is no legend
 304                  if (empty($table->legend)) {
 305                      // add button to show/hide question text
 306                      if (!isset($table->stat[0])) {
 307                          $button = $is_html ? hotpot_showhide_button($showhideid) : "";
 308                          $table->stat[0] = array(get_string('question', 'quiz').$button);
 309                      }
 310                      // add the question name/text
 311                      $name = hotpot_get_question_name($questions[$id]);
 312                      $table->stat[$row++][$col+1] = $div_start.$bold_start.$name.$bold_end.$div_end.$space;
 313                  }
 314                  // add details about each field
 315                  foreach ($fields as $field) {
 316                      // check this row is required
 317                      if ($f[$field]['count']) {
 318                          $values = array();
 319                          $string_type = array_search($field, $string_fields);
 320                          // get the value of each response to this field
 321                          // and the count of that value
 322                          foreach ($q[$id][$field] as $value => $count) {
 323                              if (is_numeric($value) && $count) {
 324                                  if (is_numeric($string_type)) {
 325                                      $value = hotpot_string($value);
 326                                      $this->set_legend($table, $col, $value, $questions[$id]);
 327                                      switch ($string_type) {
 328                                          case 0: // correct
 329                                              $font_start = $font_red;
 330                                              break;
 331                                          case 1: // wrong
 332                                              $font_start = $font_blue;
 333                                              break;
 334                                          case 2: // ignored
 335                                              $font_start = $font_brown;
 336                                              break;
 337                                      }
 338                                  } else { // numeric field
 339                                      $font_start = $font_green;
 340                                  }
 341                                  $values[] = $font_start.round(100*$count/$q[$id]['count']['total']).'%'.$font_end.' '.$value;
 342                              }
 343                          } // end foreach $value => $count
 344                          // initialize stat(istics) row for this field, if required
 345                          if (!isset($table->stat[$row])) {
 346                              $table->stat[$row] = array(get_string($field, 'hotpot'));
 347                          }
 348                          // sort the values by frequency (using user-defined function)
 349                          usort($values, "hotpot_sort_stat_values");
 350                          // add stat(istics) values for this field
 351                          $table->stat[$row++][$col+1] = count($values) ? implode($br, $values) : $space;
 352                      }
 353                  } // end foreach field
 354                  // default percent correct and discrimination index for this question
 355                  $average = $no_value;
 356                  $percent = $no_value;
 357                  $d_index = $no_value;
 358                  if (isset($q[$id]['count'])) {
 359                      // average and percent correct
 360                      if ($q[$id]['count']['total']) {
 361                          $average = round($q[$id]['count']['sum'] / $q[$id]['count']['total']).'%';
 362                          $percent = round(100*$q[$id]['count']['correct'] / $q[$id]['count']['total']).'%';
 363                          $percent .= ' ('.$q[$id]['count']['correct'].'/'.$q[$id]['count']['total'].')';
 364                      }
 365                      // discrimination index
 366                      if ($q[$id]['count']['lo']) {
 367                          $d_index = min($max_d_index, round($q[$id]['count']['hi'] / $q[$id]['count']['lo'], 1));
 368                      } else {
 369                          $d_index = $q[$id]['count']['hi'] ? $max_d_index : 0;
 370                      }
 371                      $d_index .= ' ('.$q[$id]['count']['hi'].'/'.$q[$id]['count']['lo'].')';
 372                  }
 373                  $table->foot[0][$col+1] = $average;
 374                  $table->foot[1][$col+1] = $percent;
 375                  $table->foot[2][$col+1] = $d_index;
 376              } // end foreach $question ($col)
 377              // add javascript to show/hide question text
 378              if (isset($table->stat[0]) && $is_html && empty($table->legend)) {
 379                  $i = count($table->stat[0]);
 380                  $table->stat[0][$i-1] .= hotpot_showhide_set($showhideid);
 381              }
 382              $tables[] = &$table;
 383              $this->create_legend_table($tables, $table);
 384          } // end if (empty($q)
 385      } // end function
 386  } // end class
 387  function hotpot_sort_stat_values($a, $b) {
 388      // sorts in descending order
 389      // assumes first chars in $a and $b are a percentage
 390      $a_val = intval(strip_tags($a));
 391      $b_val = intval(strip_tags($b));
 392      return ($a_val<$b_val) ? 1 : ($a_val==$b_val ? 0 : -1);
 393  }
 394  function hotpot_showhide_button($id) {
 395      $show = get_string('show');
 396      $hide = get_string('hide');
 397      $pref = '1';
 398      $text = ($pref=='1' ? $hide : $show);
 399  return <<<SHOWHIDE_BUTTON
 400  <script type="text/javascript">
 401  //<![CDATA[
 402  	function showhide (id, toggle) {
 403          var show = true;
 404          obj = document.getElementById(id+'pref');
 405          if (obj) {
 406              show = (obj.value=='1');
 407              if (toggle) {
 408                  show = !show;
 409                  obj.value = (show ? '1' :  '0');
 410              }
 411          }
 412          obj = document.getElementById(id+'button');
 413          if (obj) {
 414              obj.value = (show ? '$hide' : '$show');
 415          }
 416          obj = document.getElementsByName(id);
 417          var i_max = obj.length;
 418          for (var i=0; i<i_max; i++) {
 419              obj[i].style.display = (show ? 'block' : 'none');
 420          }
 421      }
 422      var showhide_allowed = (document.getElementById && document.getElementsByName);
 423      if (showhide_allowed) {
 424          var html = '';
 425          html += '<form onsubmit="return false">';
 426          html += '<input type="button" value="$text" id="{$id}button" onClick="javascript: return showhide(\\'$id\\', true);" />';
 427          html += '<input type="hidden" name="{$id}pref" id="{$id}pref" value="$pref" />';
 428          html += '</form>';
 429          document.writeln(html);
 430      }
 431  //]]>
 432  </script>
 433  SHOWHIDE_BUTTON
 434  ;
 435  }
 436  function hotpot_showhide_set($id) {
 437  return <<<SHOWHIDE_SET
 438  <script type="text/javascript">
 439  //<![CDATA[
 440      if (showhide_allowed) {
 441          showhide('$id');
 442      }
 443  //]]>
 444  </script>
 445  SHOWHIDE_SET
 446  ;
 447  }
 448  ?>


Generated: Wed Jan 14 11:33:29 2009 Cross-referenced by PHPXref 0.7