|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 // This file is part of Moodle - http://moodle.org/ 00003 // 00004 // Moodle is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // Moodle is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 00016 00028 defined('MOODLE_INTERNAL') || die(); 00029 00030 00038 class quiz_statistics_response_analyser { 00040 protected $questiondata; 00041 protected $loaded = false; 00042 00053 public $responses = array(); 00054 00059 public $responseclasses = array(); 00060 00066 public function __construct($questiondata) { 00067 $this->questiondata = $questiondata; 00068 00069 $this->responseclasses = 00070 question_bank::get_qtype($questiondata->qtype)->get_possible_responses( 00071 $questiondata); 00072 foreach ($this->responseclasses as $subpartid => $responseclasses) { 00073 foreach ($responseclasses as $responseclassid => $notused) { 00074 $this->responses[$subpartid][$responseclassid] = array(); 00075 } 00076 } 00077 } 00078 00082 public function has_subparts() { 00083 return count($this->responseclasses) > 1; 00084 } 00085 00090 public function has_response_classes() { 00091 foreach ($this->responseclasses as $partclasses) { 00092 if (count($partclasses) > 1) { 00093 return true; 00094 } 00095 } 00096 return false; 00097 } 00098 00104 public function has_actual_responses() { 00105 foreach ($this->responseclasses as $subpartid => $partclasses) { 00106 foreach ($partclasses as $responseclassid => $modelresponse) { 00107 $numresponses = count($this->responses[$subpartid][$responseclassid]); 00108 if ($numresponses > 1) { 00109 return true; 00110 } 00111 $actualresponse = key($this->responses[$subpartid][$responseclassid]); 00112 if ($numresponses == 1 && $actualresponse != $modelresponse->responseclass) { 00113 return true; 00114 } 00115 } 00116 } 00117 return false; 00118 } 00119 00125 public function analyse($qubaids) { 00126 // Load data. 00127 $dm = new question_engine_data_mapper(); 00128 $questionattempts = $dm->load_attempts_at_question($this->questiondata->id, $qubaids); 00129 00130 // Analyse it. 00131 foreach ($questionattempts as $qa) { 00132 $this->add_data_from_one_attempt($qa); 00133 } 00134 00135 $this->loaded = true; 00136 } 00137 00142 protected function add_data_from_one_attempt(question_attempt $qa) { 00143 $blankresponse = question_classified_response::no_response(); 00144 00145 $partresponses = $qa->classify_response(); 00146 foreach ($partresponses as $subpartid => $partresponse) { 00147 if (!isset($this->responses[$subpartid][$partresponse->responseclassid] 00148 [$partresponse->response])) { 00149 $resp = new stdClass(); 00150 $resp->count = 0; 00151 if (!is_null($partresponse->fraction)) { 00152 $resp->fraction = $partresponse->fraction; 00153 } else { 00154 $resp->fraction = $this->responseclasses[$subpartid] 00155 [$partresponse->responseclassid]->fraction; 00156 } 00157 00158 $this->responses[$subpartid][$partresponse->responseclassid] 00159 [$partresponse->response] = $resp; 00160 } 00161 00162 $this->responses[$subpartid][$partresponse->responseclassid] 00163 [$partresponse->response]->count += 1; 00164 } 00165 } 00166 00175 public function load_cached($quizstatisticsid) { 00176 global $DB; 00177 00178 $rows = $DB->get_records('quiz_question_response_stats', 00179 array('quizstatisticsid' => $quizstatisticsid, 00180 'questionid' => $this->questiondata->id)); 00181 if (!$rows) { 00182 return false; 00183 } 00184 00185 foreach ($rows as $row) { 00186 $this->responses[$row->subqid][$row->aid][$row->response]->count = $row->rcount; 00187 $this->responses[$row->subqid][$row->aid][$row->response]->fraction = $row->credit; 00188 } 00189 $this->loaded = true; 00190 return true; 00191 } 00192 00198 public function store_cached($quizstatisticsid) { 00199 global $DB; 00200 00201 if (!$this->loaded) { 00202 throw new coding_exception( 00203 'Question responses have not been analyised. Cannot store in the database.'); 00204 } 00205 00206 foreach ($this->responses as $subpartid => $partdata) { 00207 foreach ($partdata as $responseclassid => $classdata) { 00208 foreach ($classdata as $response => $data) { 00209 $row = new stdClass(); 00210 $row->quizstatisticsid = $quizstatisticsid; 00211 $row->questionid = $this->questiondata->id; 00212 $row->subqid = $subpartid; 00213 if ($responseclassid === '') { 00214 $row->aid = null; 00215 } else { 00216 $row->aid = $responseclassid; 00217 } 00218 $row->response = $response; 00219 $row->rcount = $data->count; 00220 $row->credit = $data->fraction; 00221 $DB->insert_record('quiz_question_response_stats', $row, false); 00222 } 00223 } 00224 } 00225 } 00226 }