ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilLOTestQuestionAdapter.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4include_once './Modules/Course/classes/Objectives/class.ilLOSettings.php';
5include_once './Modules/Course/classes/Objectives/class.ilLOTestAssignments.php';
6
14{
18 protected $logger = null;
19
20 protected $settings = NULL;
21 protected $assignments = null;
22
23 protected $user_id = 0;
24 protected $container_id = 0;
25
26 protected $testRefId = null;
27
33 public function __construct($a_user_id, $a_course_id)
34 {
35 $this->logger = $GLOBALS['DIC']->logger()->crs();
36
37 $this->user_id = $a_user_id;
38 $this->container_id = $a_course_id;
39
40 $this->settings = ilLOSettings::getInstanceByObjId($this->container_id);
41 $this->assignments = ilLOTestAssignments::getInstance($this->container_id);
42 }
43
47 public function getTestRefId()
48 {
49 return $this->testRefId;
50 }
51
55 public function setTestRefId($testRefId)
56 {
57 $this->testRefId = $testRefId;
58 }
59
64 protected function lookupRelevantObjectiveIdsForTest($a_container_id, $a_tst_ref_id, $a_user_id)
65 {
66 include_once './Modules/Course/classes/Objectives/class.ilLOTestAssignments.php';
68
69 include_once './Modules/Course/classes/class.ilCourseObjective.php';
70 $objective_ids = ilCourseObjective::_getObjectiveIds($a_container_id);
71
72 $relevant_objective_ids = array();
73 if(!$this->getSettings()->hasSeparateInitialTests())
74 {
75 if($a_tst_ref_id == $this->getSettings()->getInitialTest())
76 {
77 $relevant_objective_ids = $objective_ids;
78 }
79 }
80 elseif(!$this->getSettings()->hasSeparateQualifiedTests())
81 {
82 if($a_tst_ref_id == $this->getSettings()->getQualifiedTest())
83 {
84 $relevant_objective_ids = $objective_ids;
85 }
86 }
87
88 foreach((array) $objective_ids as $objective_id)
89 {
90 $assigned_itest = $assignments->getTestByObjective($objective_id, ilLOSettings::TYPE_TEST_INITIAL);
91 if($assigned_itest == $a_tst_ref_id)
92 {
93 $relevant_objective_ids[] = $objective_id;
94 }
95 $assigned_qtest = $assignments->getTestByObjective($objective_id, ilLOSettings::TYPE_TEST_QUALIFIED);
96 if($assigned_qtest == $a_tst_ref_id)
97 {
98 $relevant_objective_ids[] = $objective_id;
99 }
100 }
101
102 $relevant_objective_ids = array_unique($relevant_objective_ids);
103
104 if(count($relevant_objective_ids) <= 1)
105 {
106 return $relevant_objective_ids;
107 }
108
109 // filter passed objectives
110 $test_type = $assignments->getTypeByTest($a_tst_ref_id);
111
112 $passed_objectives = array();
113 include_once './Modules/Course/classes/Objectives/class.ilLOUserResults.php';
114 $results = new ilLOUserResults($a_container_id,$a_user_id);
115
116 $passed = $results->getCompletedObjectiveIds();
117 $this->logger->debug('Passed objectives are ' . print_r($passed,true). ' for test type: ' . $test_type);
118
119
120 // all completed => show all objectives
121 if(count($passed) >= count($relevant_objective_ids))
122 {
123 return $relevant_objective_ids;
124 }
125
126 $unpassed = array();
127 foreach($relevant_objective_ids as $objective_id)
128 {
129 if(!in_array($objective_id, $passed))
130 {
131 $unpassed[] = $objective_id;
132 }
133 }
134 return $unpassed;
135 }
136
137
143 public function notifyTestStart(ilTestSession $a_test_session, $a_test_obj_id)
144 {
145 $relevant_objectives = $this->lookupRelevantObjectiveIdsForTest(
146 $a_test_session->getObjectiveOrientedContainerId(),
147 $a_test_session->getRefId(),
148 $a_test_session->getUserId()
149 );
150 $this->logger->debug('Notify test start: '. print_r($relevant_objectives,true));
151
152 // delete test runs
153 include_once './Modules/Course/classes/Objectives/class.ilLOTestRun.php';
155 $a_test_session->getObjectiveOrientedContainerId(),
156 $a_test_session->getUserId(),
157 $a_test_obj_id
158 );
159
160 foreach((array) $relevant_objectives as $oid)
161 {
162 $this->logger->debug('Adding new run for objective with id: ' . $oid);
163 $run = new ilLOTestRun(
164 $a_test_session->getObjectiveOrientedContainerId(),
165 $a_test_session->getUserId(),
166 $a_test_obj_id,
167 $oid
168 );
169 $run->create();
170 }
171
172 // finally reinitialize test runs
173 $this->initTestRun($a_test_session);
174 }
175
181 public function prepareTestPass(ilTestSession $a_test_session, ilTestSequence $a_test_sequence)
182 {
183 $this->logger->debug('Prepare test pass called');
184
185 $this->updateQuestions($a_test_session, $a_test_sequence);
186
187 if($this->getSettings()->getPassedObjectiveMode() == ilLOSettings::MARK_PASSED_OBJECTIVE_QST)
188 {
189 $this->setQuestionsOptional($a_test_sequence);
190 }
191 elseif($this->getSettings()->getPassedObjectiveMode() == ilLOSettings::HIDE_PASSED_OBJECTIVE_QST)
192 {
193 $this->hideQuestions($a_test_sequence);
194 }
195
196 $this->storeTestRun();
197 $this->initUserResult($a_test_session);
198
199 // Save test sequence
200 $a_test_sequence->saveToDb();
201
202 return true;
203 }
204
210 {
211 $testType = $this->assignments->getTypeByTest($this->getTestRefId());
212
213 if($testType == ilLOSettings::TYPE_TEST_INITIAL && $this->getSettings()->hasSeparateInitialTests())
214 {
215 $this->buildQuestionRelatedObjectiveListByTest($a_test_sequence, $a_objectives_list);
216 }
217 elseif($testType == ilLOSettings::TYPE_TEST_QUALIFIED && $this->getSettings()->hasSeparateQualifiedTests())
218 {
219 $this->buildQuestionRelatedObjectiveListByTest($a_test_sequence, $a_objectives_list);
220 }
221 else
222 {
223 $this->buildQuestionRelatedObjectiveListByQuestions($a_test_sequence, $a_objectives_list);
224 }
225 }
226
228 {
229 $objectiveIds = array($this->getRelatedObjectivesForSeparatedTest($this->getTestRefId()));
230
231 foreach( $a_test_sequence->getQuestionIds() as $questionId )
232 {
233 $a_objectives_list->addQuestionRelatedObjectives($questionId, $objectiveIds);
234 }
235 }
236
238 {
239 foreach( $a_test_sequence->getQuestionIds() as $questionId )
240 {
241 if( $a_test_sequence instanceof ilTestRandomQuestionSequence )
242 {
243 $definitionId = $a_test_sequence->getResponsibleSourcePoolDefinitionId($questionId);
244 $objectiveIds = $this->lookupObjectiveIdByRandomQuestionSelectionDefinitionId($definitionId);
245 }
246 else
247 {
248 $objectiveIds = $this->lookupObjectiveIdByFixedQuestionId($questionId);
249 }
250
251 if( count($objectiveIds) )
252 {
253 $a_objectives_list->addQuestionRelatedObjectives($questionId, $objectiveIds);
254 }
255 }
256 }
257
259 {
260 include_once './Modules/Course/classes/Objectives/class.ilLORandomTestQuestionPools.php';
262 }
263
264 protected function lookupObjectiveIdByFixedQuestionId($a_question_id)
265 {
266 include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
268 }
269
271 {
272 foreach( $this->getAssignments()->getAssignments() as $assignment )
273 {
274 if($assignment->getTestRefId() == $testRefId)
275 {
276 return $assignment->getObjectiveId();
277 }
278 }
279
280 return null;
281 }
282
283 protected function getUserId()
284 {
285 return $this->user_id;
286 }
287
288 protected function getContainerId()
289 {
290 return $this->container_id;
291 }
292
297 protected function getSettings()
298 {
299 return $this->settings;
300 }
301
306 protected function getAssignments()
307 {
308 return $this->assignments;
309 }
310
314 protected function initUserResult(ilTestSession $session)
315 {
316 // check if current test is start object and fullfilled
317 // if yes => do not increase tries.
318 $is_qualified_run = false;
319 if($this->isQualifiedStartRun($session))
320 {
321 $is_qualified_run = true;
322 }
323
324 foreach($this->run as $run)
325 {
326 include_once './Modules/Course/classes/Objectives/class.ilLOUserResults.php';
327 include_once './Modules/Course/classes/Objectives/class.ilLOUtils.php';
328
329 $old_result = ilLOUserResults::lookupResult(
330 $this->container_id,
331 $this->user_id,
332 $run->getObjectiveId(),
333 $this->getAssignments()->getTypeByTest($session->getRefId())
334 );
335
336 include_once './Modules/Course/classes/Objectives/class.ilLOUtils.php';
337
339 $this->container_id,
340 $run->getObjectiveId(),
341 $session->getRefId(),
342 $run->getMaxPoints()
343 );
344
345 $max_attempts = ilLOUtils::lookupMaxAttempts(
346 $this->container_id,
347 $run->getObjectiveId(),
348 $session->getRefId()
349 );
350
351 $this->logger->debug('Max attempts = ' . $max_attempts);
352
353 if($max_attempts)
354 {
355 // check if current test is start object and fullfilled
356 // if yes => do not increase tries.
357 $this->logger->debug('Checking for qualified test...');
358 if(!$is_qualified_run)
359 {
360 $this->logger->debug(' and increasing attempts.');
361 ++$old_result['tries'];
362 }
363 $old_result['is_final'] = ($old_result['tries'] >= $max_attempts);
364 }
365
366 $ur = new ilLOUserResults($this->container_id,$this->user_id);
367 $ur->saveObjectiveResult(
368 $run->getObjectiveId(),
369 $this->getAssignments()->getTypeByTest($session->getRefId()),
370 $old_result['status'],
371 $old_result['result_perc'],
372 $limit,
373 $old_result['tries'],
374 $old_result['is_final']
375 );
376 }
377 }
378
384 protected function isQualifiedStartRun(ilTestSession $session)
385 {
386 if($this->getAssignments()->getTypeByTest($session->getRefId()) == ilLOSettings::TYPE_TEST_INITIAL)
387 {
388 $this->logger->debug('Initial test');
389 return false;
390 }
391
392 if($session->getRefId() != $this->getSettings()->getQualifiedTest())
393 {
394 $this->logger->debug('No qualified test run');
395 return false;
396 }
397 include_once './Services/Container/classes/class.ilContainerStartObjects.php';
399 {
400 $this->logger->debug('No start object');
401 return false;
402 }
403 // Check if start object is fullfilled
404
405 $container_ref_ids = ilObject::_getAllReferences($this->getContainerId());
406 $container_ref_id = end($container_ref_ids);
407
409 $container_ref_id,
410 $this->getContainerId()
411 );
412 if($start->isFullfilled($this->getUserId(),$session->getRefId()))
413 {
414 $this->logger->debug('Is fullfilled');
415 return false;
416 }
417 $this->logger->debug('Is not fullfilled');
418 return true;
419 }
420
426 public function updateQuestionResult(ilTestSession $session, assQuestion $qst)
427 {
428 foreach($this->run as $run)
429 {
430 if($run->questionExists($qst->getId()))
431 {
432 $GLOBALS['ilLog']->write(__METHOD__.': reached points are '.$qst->getReachedPoints($session->getActiveId(),$session->getPass()));
433 $run->setQuestionResult(
434 $qst->getId(),
435 $qst->getReachedPoints($session->getActiveId(),$session->getPass())
436 );
437 $run->update();
438
439 $res = $run->getResult();
440
441 include_once './Modules/Course/classes/Objectives/class.ilLOUserResults.php';
442 include_once './Modules/Course/classes/Objectives/class.ilLOUtils.php';
443
444 $old_result = ilLOUserResults::lookupResult(
445 $this->container_id,
446 $this->user_id,
447 $run->getObjectiveId(),
448 $this->getAssignments()->getTypeByTest($session->getRefId())
449 );
450
451 $ur = new ilLOUserResults($this->container_id,$this->user_id);
452 $ur->saveObjectiveResult(
453 $run->getObjectiveId(),
454 $this->getAssignments()->getTypeByTest($session->getRefId()),
456 $this->container_id,
457 $session->getRefId(),
458 $run->getObjectiveId(),
459 $res['max'],$res['reached'],$old_result['limit_perc']) ?
462 (int) $res['percentage'],
463 $old_result['limit_perc'],
464 $old_result['tries'],
465 $old_result['is_final']
466 );
467 $GLOBALS['ilLog']->write(__METHOD__.': '.print_r($run->getResult(),true));
468 $GLOBALS['ilLog']->write(__METHOD__.'!!!!!!!!!!!!!!!!!!!!: '.print_r($comp,TRUE));
469
470 include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
471 ilLPStatusWrapper::_updateStatus($this->container_id,$this->user_id);
472 }
473 }
474 return false;
475 }
476
481 protected function setQuestionsOptional(ilTestSequence $seq)
482 {
483 // first unset optional on all questions
485 foreach($seq->getQuestionIds() as $qid)
486 {
487 if(!$this->isInRun($qid)) // but is assigned to any LO
488 {
489 $seq->setQuestionOptional($qid);
490 }
491 }
492 }
493
498 protected function hideQuestions(ilTestSequence $seq)
499 {
500 // first unhide all questions
501 $seq->clearHiddenQuestions();
502 foreach($seq->getQuestionIds() as $qid)
503 {
504 if(!$this->isInRun($qid))
505 {
506 $seq->hideQuestion($qid);
507 }
508 }
509 }
510
511 protected function initTestRun(ilTestSession $session)
512 {
513 include_once './Modules/Course/classes/Objectives/class.ilLOTestRun.php';
514 $this->run = ilLOTestRun::getRun(
515 $this->container_id,
516 $this->user_id,
518 );
519 }
520
524 protected function storeTestRun()
525 {
526 foreach ($this->run as $tst_run)
527 {
528 $tst_run->update();
529 }
530 }
531
532
533 protected function updateQuestions(ilTestSession $session, ilTestSequence $seq)
534 {
535 if($this->getAssignments()->isSeparateTest($session->getRefId()))
536 {
537 $GLOBALS['ilLog']->write(__METHOD__.': separate run');
538 return $this->updateSeparateTestQuestions($session, $seq);
539 }
540 if($seq instanceof ilTestSequenceFixedQuestionSet)
541 {
542 $GLOBALS['ilLog']->write(__METHOD__.': fixed run');
543 return $this->updateFixedQuestions($session, $seq);
544 }
545 if($seq instanceof ilTestSequenceRandomQuestionSet)
546 {
547 $GLOBALS['ilLog']->write(__METHOD__.': random run');
548 return $this->updateRandomQuestions($session, $seq);
549 }
550
551 }
552
559 {
560 foreach($this->run as $tst_run)
561 {
562 $tst_run->clearQuestions();
563 $points = 0;
564 foreach($seq->getQuestionIds() as $idx => $qst_id)
565 {
566 $tst_run->addQuestion($qst_id);
567 include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
569 }
570 $tst_run->setMaxPoints($points);
571 }
572 }
573
574
575 protected function updateFixedQuestions(ilTestSession $session, ilTestSequence $seq)
576 {
577 foreach ($this->run as $tst_run)
578 {
579 $tst_run->clearQuestions();
580 include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
582 ilObject::_lookupObjId($session->getRefId()),
583 $tst_run->getObjectiveId()
584 );
585 $points = 0;
586 foreach($qst as $id)
587 {
588 $tst_run->addQuestion($id);
590 }
591 $tst_run->setMaxPoints($points);
592 }
593 }
594
596 {
597 include_once './Modules/Course/classes/Objectives/class.ilLORandomTestQuestionPools.php';
598 include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
599
600 foreach($this->run as $tst_run)
601 {
602 // Clear questions of previous run
603 $tst_run->clearQuestions();
605 $this->container_id,
606 $tst_run->getObjectiveId(),
607 ($this->getSettings()->getQualifiedTest() == $session->getRefId() ?
610 );
611 $stored_sequence_id = $rnd->getQplSequence();
612 $points = 0;
613 foreach($seq->getQuestionIds() as $qst)
614 {
615 if($stored_sequence_id == $seq->getResponsibleSourcePoolDefinitionId($qst))
616 {
617 $tst_run->addQuestion($qst);
619 }
620 }
621 $tst_run->setMaxPoints($points);
622 }
623 }
624
625 protected function isInRun($a_qid)
626 {
627 foreach($this->run as $run)
628 {
629 if($run->questionExists($a_qid))
630 {
631 return true;
632 }
633 }
634 return false;
635 }
636
637
638 private static function getQuestionData($testObjId, $questionIds)
639 {
640 global $ilDB, $lng, $ilPluginAdmin;
641
642 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionList.php';
643 $questionList = new ilAssQuestionList($ilDB, $lng, $ilPluginAdmin);
644 $questionList->setParentObjId($testObjId);
645
646 $questionList->setQuestionInstanceTypeFilter(ilAssQuestionList::QUESTION_INSTANCE_TYPE_DUPLICATES);
647 $questionList->setQuestionIdsFilter($questionIds);
648
649 $questionList->load();
650
651 return $questionList->getQuestionDataArray();
652 }
653
654 public static function getInstance(ilTestSession $a_test_session)
655 {
656 $adapter = new self(
657 $a_test_session->getUserId(),
658 $a_test_session->getObjectiveOrientedContainerId()
659 );
660
661 $adapter->setTestRefId($a_test_session->getRefId());
662 $adapter->initTestRun($a_test_session);
663
664 return $adapter;
665 }
666}
667?>
An exception for terminatinating execution or to throw for unit testing.
Abstract basic class which is to be extended by the concrete assessment question type classes.
getId()
Gets the id of the assQuestion object.
getReachedPoints($active_id, $pass=NULL)
Returns the points, a learner has reached answering the question This is the fast way to get the poin...
static isStartObject($a_container_id, $a_item_ref_id)
Check if object is start object @global type $ilDB.
static lookupObjectivesOfQuestion($a_qid)
Lookup objective for test question @global type $ilDB.
static lookupQuestionsByObjective($a_test_id, $a_objective)
static _lookupMaximumPointsOfQuestion($a_question_id)
lookup maximimum point
static _getObjectiveIds($course_id, $a_activated_only=false)
static lookupObjectiveIdsBySequence($a_container_id, $a_seq_id)
Lookup objective id by sequence.
const HIDE_PASSED_OBJECTIVE_QST
const MARK_PASSED_OBJECTIVE_QST
static getInstanceByObjId($a_obj_id)
get singleton instance
static getInstance($a_container_id)
Get instance by container id.
setQuestionsOptional(ilTestSequence $seq)
set questions optional
isQualifiedStartRun(ilTestSession $session)
Check if current run is a start object run.
buildQuestionRelatedObjectiveListByQuestions(ilTestQuestionSequence $a_test_sequence, ilTestQuestionRelatedObjectivesList $a_objectives_list)
buildQuestionRelatedObjectiveListByTest(ilTestQuestionSequence $a_test_sequence, ilTestQuestionRelatedObjectivesList $a_objectives_list)
prepareTestPass(ilTestSession $a_test_session, ilTestSequence $a_test_sequence)
Called from learning objective test.
buildQuestionRelatedObjectiveList(ilTestQuestionSequence $a_test_sequence, ilTestQuestionRelatedObjectivesList $a_objectives_list)
notifyTestStart(ilTestSession $a_test_session, $a_test_obj_id)
Called from learning objective test on actual test start.
hideQuestions(ilTestSequence $seq)
Hide questions.
updateQuestions(ilTestSession $session, ilTestSequence $seq)
updateQuestionResult(ilTestSession $session, assQuestion $qst)
update question result of run
updateSeparateTestQuestions(ilTestSession $session, ilTestSequence $seq)
Update questions for separate tests.
updateRandomQuestions(ilTestSession $session, ilTestSequenceRandomQuestionSet $seq)
lookupRelevantObjectiveIdsForTest($a_container_id, $a_tst_ref_id, $a_user_id)
Lookup all relevant objective ids for a specific test.
initUserResult(ilTestSession $session)
init user result
static getInstance(ilTestSession $a_test_session)
__construct($a_user_id, $a_course_id)
static getQuestionData($testObjId, $questionIds)
updateFixedQuestions(ilTestSession $session, ilTestSequence $seq)
Stores current objective, questions and max points.
static deleteRun($a_container_id, $a_user_id, $a_test_id)
static getRun($a_container_id, $a_user_id, $a_test_id)
static lookupResult($a_course_obj_id, $a_user_id, $a_objective_id, $a_tst_type)
Lookup user result.
static lookupObjectiveRequiredPercentage($a_container_id, $a_objective_id, $a_test_ref_id, $a_max_points)
static isCompleted($a_cont_oid, $a_test_rid, $a_objective_id, $max_points, $reached, $limit_perc)
Check if objective is completed.
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
static _lookupObjId($a_id)
static _getAllReferences($a_id)
get all reference ids of object
Test sequence handler.
hideQuestion($question_id)
saveToDb()
Saves the sequence data for a given pass to the database.
setQuestionOptional($questionId)
Test session handler.
getRefId()
Get Ref id.
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
global $lng
Definition: privfeed.php:17
$results
settings()
Definition: settings.php:2
global $ilDB