1<?php 2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4/** 5 * Service class for tests. 6 * 7 * @author Björn Heyser <bheyser@databay.de> 8 * @version $Id$ 9 * 10 * @ingroup ModulesTest 11 */ 12class ilTestService 13{ 14 /** 15 * @access protected 16 * @var ilObjTest 17 */ 18 protected $object = null; 19 20 /** 21 * @access public 22 * @param ilObjTest $a_object 23 */ 24 public function __construct(ilObjTest $a_object) 25 { 26 $this->object = $a_object; 27 } 28 29 /** 30 * @access public 31 * @global ilObjUser $ilUser 32 * @param integer $active_id 33 * @param boolean $short 34 * @return array $passOverwiewData 35 */ 36 public function getPassOverviewData($active_id, $short = false) 37 { 38 $passOverwiewData = array(); 39 40 global $DIC; 41 $ilUser = $DIC['ilUser']; 42 43 $scoredPass = $this->object->_getResultPass($active_id); 44 $lastPass = ilObjTest::_getPass($active_id); 45 46 $testPercentage = 0; 47 $testReachedPoints = 0; 48 $testMaxPoints = 0; 49 50 for ($pass = 0; $pass <= $lastPass; $pass++) { 51 $passFinishDate = ilObjTest::lookupPassResultsUpdateTimestamp($active_id, $pass); 52 53 if ($passFinishDate <= 0) { 54 continue; 55 } 56 57 if (!$short) { 58 $resultData = &$this->object->getTestResult($active_id, $pass); 59 60 if (!$resultData["pass"]["total_max_points"]) { 61 $passPercentage = 0; 62 } else { 63 $passPercentage = ($resultData["pass"]["total_reached_points"] / $resultData["pass"]["total_max_points"]) * 100; 64 } 65 66 $passMaxPoints = $resultData["pass"]["total_max_points"]; 67 $passReachedPoints = $resultData["pass"]["total_reached_points"]; 68 69 $passAnsweredQuestions = $this->object->getAnsweredQuestionCount($active_id, $pass); 70 $passTotalQuestions = count($resultData) - 2; 71 72 if ($pass == $scoredPass) { 73 $isScoredPass = true; 74 75 if (!$resultData["test"]["total_max_points"]) { 76 $testPercentage = 0; 77 } else { 78 $testPercentage = ($resultData["test"]["total_reached_points"] / $resultData["test"]["total_max_points"]) * 100; 79 } 80 81 $testMaxPoints = $resultData["test"]["total_max_points"]; 82 $testReachedPoints = $resultData["test"]["total_reached_points"]; 83 84 $passOverwiewData['test'] = array( 85 'active_id' => $active_id, 86 'scored_pass' => $scoredPass, 87 'max_points' => $testMaxPoints, 88 'reached_points' => $testReachedPoints, 89 'percentage' => $testPercentage 90 ); 91 } else { 92 $isScoredPass = false; 93 } 94 95 $passOverwiewData['passes'][] = array( 96 'active_id' => $active_id, 97 'pass' => $pass, 98 'finishdate' => $passFinishDate, 99 'max_points' => $passMaxPoints, 100 'reached_points' => $passReachedPoints, 101 'percentage' => $passPercentage, 102 'answered_questions' => $passAnsweredQuestions, 103 'total_questions' => $passTotalQuestions, 104 'is_scored_pass' => $isScoredPass 105 ); 106 } 107 } 108 109 return $passOverwiewData; 110 } 111 112 /** 113 * Returns the list of answers of a users test pass and offers a scoring option 114 * 115 * @access public 116 * @param integer $active_id Active ID of the active user 117 * @param integer $pass Test pass 118 * @return string HTML code of the list of answers 119 */ 120 public function getManScoringQuestionGuiList($activeId, $pass) 121 { 122 include_once "./Modules/Test/classes/class.ilObjAssessmentFolder.php"; 123 $manScoringQuestionTypes = ilObjAssessmentFolder::_getManualScoring(); 124 125 $testResultData = $this->object->getTestResult($activeId, $pass); 126 127 $manScoringQuestionGuiList = array(); 128 129 foreach ($testResultData as $questionData) { 130 if (!isset($questionData['qid'])) { 131 continue; 132 } 133 134 if (!isset($questionData['type'])) { 135 throw new ilTestException('no question type given!'); 136 } 137 138 $questionGUI = $this->object->createQuestionGUI("", $questionData['qid']); 139 140 if (!in_array($questionGUI->object->getQuestionTypeID(), $manScoringQuestionTypes)) { 141 continue; 142 } 143 144 $manScoringQuestionGuiList[ $questionData['qid'] ] = $questionGUI; 145 } 146 147 return $manScoringQuestionGuiList; 148 } 149 150 /** 151 * reads the flag wether manscoring is done for the given test active or not 152 * from the global settings (scope: assessment / key: manscoring_done_<activeId>) 153 * 154 * @access public 155 * @static 156 * @param integer $activeId 157 * @return boolean $manScoringDone 158 */ 159 public static function isManScoringDone($activeId) 160 { 161 $assessmentSetting = new ilSetting("assessment"); 162 return $assessmentSetting->get("manscoring_done_" . $activeId, false); 163 } 164 165 /** 166 * stores the flag wether manscoring is done for the given test active or not 167 * within the global settings (scope: assessment / key: manscoring_done_<activeId>) 168 * 169 * @access public 170 * @static 171 * @param integer $activeId 172 * @param boolean $manScoringDone 173 */ 174 public static function setManScoringDone($activeId, $manScoringDone) 175 { 176 $assessmentSetting = new ilSetting("assessment"); 177 $assessmentSetting->set("manscoring_done_" . $activeId, (bool) $manScoringDone); 178 } 179 180 public function buildVirtualSequence(ilTestSession $testSession) 181 { 182 global $DIC; 183 $ilDB = $DIC['ilDB']; 184 $lng = $DIC['lng']; 185 $ilPluginAdmin = $DIC['ilPluginAdmin']; 186 187 require_once 'Modules/Test/classes/class.ilTestVirtualSequence.php'; 188 $testSequenceFactory = new ilTestSequenceFactory($ilDB, $lng, $ilPluginAdmin, $this->object); 189 190 if ($this->object->isRandomTest()) { 191 require_once 'Modules/Test/classes/class.ilTestVirtualSequenceRandomQuestionSet.php'; 192 $virtualSequence = new ilTestVirtualSequenceRandomQuestionSet($ilDB, $this->object, $testSequenceFactory); 193 } else { 194 require_once 'Modules/Test/classes/class.ilTestVirtualSequence.php'; 195 $virtualSequence = new ilTestVirtualSequence($ilDB, $this->object, $testSequenceFactory); 196 } 197 198 $virtualSequence->setActiveId($testSession->getActiveId()); 199 200 $virtualSequence->init(); 201 202 return $virtualSequence; 203 } 204 205 public function getVirtualSequenceUserResults(ilTestVirtualSequence $virtualSequence) 206 { 207 $resultsByPass = array(); 208 209 foreach ($virtualSequence->getUniquePasses() as $pass) { 210 $results = $this->object->getTestResult( 211 $virtualSequence->getActiveId(), 212 $pass, 213 false, 214 true, 215 true 216 ); 217 218 $resultsByPass[$pass] = $results; 219 } 220 221 $virtualPassResults = array(); 222 223 foreach ($virtualSequence->getQuestionsPassMap() as $questionId => $pass) { 224 foreach ($resultsByPass[$pass] as $key => $questionResult) { 225 if ($key === 'test' || $key === 'pass') { 226 continue; 227 } 228 229 if ($questionResult['qid'] == $questionId) { 230 $questionResult['pass'] = $pass; 231 $virtualPassResults[$questionId] = $questionResult; 232 break; 233 } 234 } 235 } 236 237 return $virtualPassResults; 238 } 239 240 /** 241 * @param ilTestSequenceSummaryProvider $testSequence 242 * @param bool $obligationsFilter 243 * @return array 244 */ 245 public function getQuestionSummaryData(ilTestSequenceSummaryProvider $testSequence, $obligationsFilterEnabled) 246 { 247 $result_array = $testSequence->getSequenceSummary($obligationsFilterEnabled); 248 249 $marked_questions = array(); 250 251 if ($this->object->getShowMarker()) { 252 include_once "./Modules/Test/classes/class.ilObjTest.php"; 253 $marked_questions = ilObjTest::_getSolvedQuestions($testSequence->getActiveId()); 254 } 255 256 $data = array(); 257 $firstQuestion = true; 258 259 foreach ($result_array as $key => $value) { 260 $disableLink = ( 261 $this->object->isFollowupQuestionAnswerFixationEnabled() 262 && !$value['presented'] && !$firstQuestion 263 ); 264 265 $description = ""; 266 if ($this->object->getListOfQuestionsDescription()) { 267 $description = $value["description"]; 268 } 269 270 $points = ""; 271 if (!$this->object->getTitleOutput()) { 272 $points = $value["points"]; 273 } 274 275 $marked = false; 276 if (count($marked_questions)) { 277 if (array_key_exists($value["qid"], $marked_questions)) { 278 $obj = $marked_questions[$value["qid"]]; 279 if ($obj["solved"] == 1) { 280 $marked = true; 281 } 282 } 283 } 284 285 // fau: testNav - add number parameter for getQuestionTitle() 286 $data[] = array( 287 'order' => $value["nr"], 288 'title' => $this->object->getQuestionTitle($value["title"], $value["nr"]), 289 'description' => $description, 290 'disabled' => $disableLink, 291 'worked_through' => $value["worked_through"], 292 'postponed' => $value["postponed"], 293 'points' => $points, 294 'marked' => $marked, 295 'sequence' => $value["sequence"], 296 'obligatory' => $value['obligatory'], 297 'isAnswered' => $value['isAnswered'] 298 ); 299 300 $firstQuestion = false; 301 // fau. 302 } 303 304 return $data; 305 } 306} 307