ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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{
15 protected $settings = NULL;
16 protected $assignments = null;
17
18 protected $user_id = 0;
19 protected $container_id = 0;
20
21 protected $testRefId = null;
22
28 public function __construct($a_user_id, $a_course_id)
29 {
30 $this->user_id = $a_user_id;
31 $this->container_id = $a_course_id;
32
33 $this->settings = ilLOSettings::getInstanceByObjId($this->container_id);
34 $this->assignments = ilLOTestAssignments::getInstance($this->container_id);
35 }
36
40 public function getTestRefId()
41 {
42 return $this->testRefId;
43 }
44
48 public function setTestRefId($testRefId)
49 {
50 $this->testRefId = $testRefId;
51 }
52
57 protected function lookupRelevantObjectiveIdsForTest($a_container_id, $a_tst_ref_id, $a_user_id)
58 {
59 include_once './Modules/Course/classes/Objectives/class.ilLOTestAssignments.php';
61
62 include_once './Modules/Course/classes/class.ilCourseObjective.php';
63 $objective_ids = ilCourseObjective::_getObjectiveIds($a_container_id);
64
65 $relevant_objective_ids = array();
66 if(!$this->getSettings()->hasSeparateInitialTests())
67 {
68 if($a_tst_ref_id == $this->getSettings()->getInitialTest())
69 {
70 $relevant_objective_ids = $objective_ids;
71 }
72 }
73 elseif(!$this->getSettings()->hasSeparateQualifiedTests())
74 {
75 if($a_tst_ref_id == $this->getSettings()->getQualifiedTest())
76 {
77 $relevant_objective_ids = $objective_ids;
78 }
79 }
80
81 foreach((array) $objective_ids as $objective_id)
82 {
83 $assigned_itest = $assignments->getTestByObjective($objective_id, ilLOSettings::TYPE_TEST_INITIAL);
84 if($assigned_itest == $a_tst_ref_id)
85 {
86 $relevant_objective_ids[] = $objective_id;
87 }
88 $assigned_qtest = $assignments->getTestByObjective($objective_id, ilLOSettings::TYPE_TEST_QUALIFIED);
89 if($assigned_qtest == $a_tst_ref_id)
90 {
91 $relevant_objective_ids[] = $objective_id;
92 }
93 }
94
95 $relevant_objective_ids = array_unique($relevant_objective_ids);
96
97 if(count($relevant_objective_ids) <= 1)
98 {
99 return $relevant_objective_ids;
100 }
101
102 // filter passed objectives
103 $test_type = $assignments->getTypeByTest($a_tst_ref_id);
104
105 $passed_objectives = array();
106 include_once './Modules/Course/classes/Objectives/class.ilLOUserResults.php';
107 $results = new ilLOUserResults($a_container_id,$a_user_id);
108
109 $passed = $results->getCompletedObjectiveIds();
110 $GLOBALS['ilLog']->write(__METHOD__.': Passed objectives are '.print_r($passed,TRUE).' test_type = '.$test_type);
111
112
113 // all completed => show all objectives
114 if(count($passed) >= count($relevant_objective_ids))
115 {
116 return $relevant_objective_ids;
117 }
118
119 $unpassed = array();
120 foreach($relevant_objective_ids as $objective_id)
121 {
122 if(!in_array($objective_id, $passed))
123 {
124 $unpassed[] = $objective_id;
125 }
126 }
127 return $unpassed;
128 }
129
130
136 public function notifyTestStart(ilTestSession $a_test_session, $a_test_obj_id)
137 {
138 $relevant_objectives = $this->lookupRelevantObjectiveIdsForTest(
139 $a_test_session->getObjectiveOrientedContainerId(),
140 $a_test_session->getRefId(),
141 $a_test_session->getUserId()
142 );
143 $GLOBALS['ilLog']->write(__METHOD__.': Notify test start ' . print_r($relevant_objectives,TRUE));
144
145 // delete test runs
146 include_once './Modules/Course/classes/Objectives/class.ilLOTestRun.php';
148 $a_test_session->getObjectiveOrientedContainerId(),
149 $a_test_session->getUserId(),
150 $a_test_obj_id
151 );
152
153 foreach((array) $relevant_objectives as $oid)
154 {
155 $GLOBALS['ilLog']->write(__METHOD__.': Adding new run for objective with id '.$oid);
156 $run = new ilLOTestRun(
157 $a_test_session->getObjectiveOrientedContainerId(),
158 $a_test_session->getUserId(),
159 $a_test_obj_id,
160 $oid
161 );
162 $run->create();
163 }
164
165 // finally reinitialize test runs
166 $this->initTestRun($a_test_session);
167 }
168
174 public function prepareTestPass(ilTestSession $a_test_session, ilTestSequence $a_test_sequence)
175 {
176 $this->updateQuestions($a_test_session, $a_test_sequence);
177
178 if($this->getSettings()->getPassedObjectiveMode() == ilLOSettings::MARK_PASSED_OBJECTIVE_QST)
179 {
180 $this->setQuestionsOptional($a_test_sequence);
181 }
182 elseif($this->getSettings()->getPassedObjectiveMode() == ilLOSettings::HIDE_PASSED_OBJECTIVE_QST)
183 {
184 $this->hideQuestions($a_test_sequence);
185 }
186
187 $this->storeTestRun();
188 $this->initUserResult($a_test_session);
189
190 // Save test sequence
191 $a_test_sequence->saveToDb();
192
193 return true;
194 }
195
201 {
202 $testType = $this->assignments->getTypeByTest($this->getTestRefId());
203
204 if($testType == ilLOSettings::TYPE_TEST_INITIAL && $this->getSettings()->hasSeparateInitialTests())
205 {
206 $this->buildQuestionRelatedObjectiveListByTest($a_test_sequence, $a_objectives_list);
207 }
208 elseif($testType == ilLOSettings::TYPE_TEST_QUALIFIED && $this->getSettings()->hasSeparateQualifiedTests())
209 {
210 $this->buildQuestionRelatedObjectiveListByTest($a_test_sequence, $a_objectives_list);
211 }
212 else
213 {
214 $this->buildQuestionRelatedObjectiveListByQuestions($a_test_sequence, $a_objectives_list);
215 }
216 }
217
219 {
220 $objectiveIds = array($this->getRelatedObjectivesForSeparatedTest($this->getTestRefId()));
221
222 foreach( $a_test_sequence->getQuestionIds() as $questionId )
223 {
224 $a_objectives_list->addQuestionRelatedObjectives($questionId, $objectiveIds);
225 }
226 }
227
229 {
230 foreach( $a_test_sequence->getQuestionIds() as $questionId )
231 {
232 if( $a_test_sequence instanceof ilTestRandomQuestionSequence )
233 {
234 $definitionId = $a_test_sequence->getResponsibleSourcePoolDefinitionId($questionId);
235 $objectiveIds = $this->lookupObjectiveIdByRandomQuestionSelectionDefinitionId($definitionId);
236 }
237 else
238 {
239 $objectiveIds = $this->lookupObjectiveIdByFixedQuestionId($questionId);
240 }
241
242 if( count($objectiveIds) )
243 {
244 $a_objectives_list->addQuestionRelatedObjectives($questionId, $objectiveIds);
245 }
246 }
247 }
248
250 {
251 include_once './Modules/Course/classes/Objectives/class.ilLORandomTestQuestionPools.php';
253 }
254
255 protected function lookupObjectiveIdByFixedQuestionId($a_question_id)
256 {
257 include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
259 }
260
262 {
263 foreach( $this->getAssignments()->getAssignments() as $assignment )
264 {
265 if($assignment->getTestRefId() == $testRefId)
266 {
267 return $assignment->getObjectiveId();
268 }
269 }
270
271 return null;
272 }
273
274 protected function getUserId()
275 {
276 return $this->user_id;
277 }
278
279 protected function getContainerId()
280 {
281 return $this->container_id;
282 }
283
288 protected function getSettings()
289 {
290 return $this->settings;
291 }
292
297 protected function getAssignments()
298 {
299 return $this->assignments;
300 }
301
305 protected function initUserResult(ilTestSession $session)
306 {
307 // check if current test is start object and fullfilled
308 // if yes => do not increase tries.
309 $is_qualified_run = false;
310 if($this->isQualifiedStartRun($session))
311 {
312 $is_qualified_run = true;
313 }
314
315 foreach($this->run as $run)
316 {
317 include_once './Modules/Course/classes/Objectives/class.ilLOUserResults.php';
318 include_once './Modules/Course/classes/Objectives/class.ilLOUtils.php';
319
320 $old_result = ilLOUserResults::lookupResult(
321 $this->container_id,
322 $this->user_id,
323 $run->getObjectiveId(),
324 $this->getAssignments()->getTypeByTest($session->getRefId())
325 );
326
327 include_once './Modules/Course/classes/Objectives/class.ilLOUtils.php';
328
330 $this->container_id,
331 $run->getObjectiveId(),
332 $session->getRefId(),
333 $run->getMaxPoints()
334 );
335
336 $max_attempts = ilLOUtils::lookupMaxAttempts($this->container_id, $run->getObjectiveId());
337 if($max_attempts)
338 {
339 // check if current test is start object and fullfilled
340 // if yes => do not increase tries.
341 $GLOBALS['ilLog']->write(__METHOD__.': check for qualified...');
342 if(!$is_qualified_run)
343 {
344 $GLOBALS['ilLog']->write(__METHOD__.': and increase attempts');
345 ++$old_result['tries'];
346 }
347 $old_result['is_final'] = ($old_result['tries'] >= $max_attempts);
348 }
349
350 $ur = new ilLOUserResults($this->container_id,$this->user_id);
351 $ur->saveObjectiveResult(
352 $run->getObjectiveId(),
353 $this->getAssignments()->getTypeByTest($session->getRefId()),
354 $old_result['status'],
355 $old_result['result_perc'],
356 $limit,
357 $old_result['tries'],
358 $old_result['is_final']
359 );
360 }
361 }
362
368 protected function isQualifiedStartRun(ilTestSession $session)
369 {
370 if($this->getAssignments()->getTypeByTest($session->getRefId()) == ilLOSettings::TYPE_TEST_INITIAL)
371 {
372 $GLOBALS['ilLog']->write(__METHOD__.': is initial');
373 return false;
374 }
375
376 if($session->getRefId() != $this->getSettings()->getQualifiedTest())
377 {
378 $GLOBALS['ilLog']->write(__METHOD__.': is not qualified');
379 return false;
380 }
381 include_once './Services/Container/classes/class.ilContainerStartObjects.php';
383 {
384 $GLOBALS['ilLog']->write(__METHOD__.': no start object');
385 return false;
386 }
387 // Check if start object is fullfilled
388
389 $container_ref_ids = ilObject::_getAllReferences($this->getContainerId());
390 $container_ref_id = end($container_ref_ids);
391
392 $start = new ilContainerStartObjects(
393 $container_ref_id,
394 $this->getContainerId()
395 );
396 if($start->isFullfilled($this->getUserId(),$session->getRefId()))
397 {
398 $GLOBALS['ilLog']->write(__METHOD__.': is fullfilled');
399
400 return false;
401 }
402 $GLOBALS['ilLog']->write(__METHOD__.': is not fullfilled');
403 return true;
404 }
405
411 public function updateQuestionResult(ilTestSession $session, assQuestion $qst)
412 {
413 foreach($this->run as $run)
414 {
415 if($run->questionExists($qst->getId()))
416 {
417 $GLOBALS['ilLog']->write(__METHOD__.': reached points are '.$qst->getReachedPoints($session->getActiveId(),$session->getPass()));
418 $run->setQuestionResult(
419 $qst->getId(),
420 $qst->getReachedPoints($session->getActiveId(),$session->getPass())
421 );
422 $run->update();
423
424 $res = $run->getResult();
425
426 include_once './Modules/Course/classes/Objectives/class.ilLOUserResults.php';
427 include_once './Modules/Course/classes/Objectives/class.ilLOUtils.php';
428
429 $old_result = ilLOUserResults::lookupResult(
430 $this->container_id,
431 $this->user_id,
432 $run->getObjectiveId(),
433 $this->getAssignments()->getTypeByTest($session->getRefId())
434 );
435
436 $ur = new ilLOUserResults($this->container_id,$this->user_id);
437 $ur->saveObjectiveResult(
438 $run->getObjectiveId(),
439 $this->getAssignments()->getTypeByTest($session->getRefId()),
441 $this->container_id,
442 $session->getRefId(),
443 $run->getObjectiveId(),
444 $res['max'],$res['reached'],$old_result['limit_perc']) ?
447 (int) $res['percentage'],
448 $old_result['limit_perc'],
449 $old_result['tries'],
450 $old_result['is_final']
451 );
452 $GLOBALS['ilLog']->write(__METHOD__.': '.print_r($run->getResult(),true));
453 $GLOBALS['ilLog']->write(__METHOD__.'!!!!!!!!!!!!!!!!!!!!: '.print_r($comp,TRUE));
454
455 include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
456 ilLPStatusWrapper::_updateStatus($this->container_id,$this->user_id);
457 }
458 }
459 return false;
460 }
461
466 protected function setQuestionsOptional(ilTestSequence $seq)
467 {
468 // first unset optional on all questions
470 foreach($seq->getQuestionIds() as $qid)
471 {
472 if(!$this->isInRun($qid)) // but is assigned to any LO
473 {
474 $seq->setQuestionOptional($qid);
475 }
476 }
477 }
478
483 protected function hideQuestions(ilTestSequence $seq)
484 {
485 // first unhide all questions
486 $seq->clearHiddenQuestions();
487 foreach($seq->getQuestionIds() as $qid)
488 {
489 if(!$this->isInRun($qid))
490 {
491 $seq->hideQuestion($qid);
492 }
493 }
494 }
495
496 protected function initTestRun(ilTestSession $session)
497 {
498 include_once './Modules/Course/classes/Objectives/class.ilLOTestRun.php';
499 $this->run = ilLOTestRun::getRun(
500 $this->container_id,
501 $this->user_id,
503 );
504 }
505
509 protected function storeTestRun()
510 {
511 foreach ($this->run as $tst_run)
512 {
513 $tst_run->update();
514 }
515 }
516
517
518 protected function updateQuestions(ilTestSession $session, ilTestSequence $seq)
519 {
520 if($this->getAssignments()->isSeparateTest($session->getRefId()))
521 {
522 $GLOBALS['ilLog']->write(__METHOD__.': separate run');
523 return $this->updateSeparateTestQuestions($session, $seq);
524 }
525 if($seq instanceof ilTestSequenceFixedQuestionSet)
526 {
527 $GLOBALS['ilLog']->write(__METHOD__.': fixed run');
528 return $this->updateFixedQuestions($session, $seq);
529 }
530 if($seq instanceof ilTestSequenceRandomQuestionSet)
531 {
532 $GLOBALS['ilLog']->write(__METHOD__.': random run');
533 return $this->updateRandomQuestions($session, $seq);
534 }
535
536 }
537
544 {
545 foreach($this->run as $tst_run)
546 {
547 $tst_run->clearQuestions();
548 $points = 0;
549 foreach($seq->getQuestionIds() as $idx => $qst_id)
550 {
551 $tst_run->addQuestion($qst_id);
552 include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
554 }
555 $tst_run->setMaxPoints($points);
556 }
557 }
558
559
560 protected function updateFixedQuestions(ilTestSession $session, ilTestSequence $seq)
561 {
562 foreach ($this->run as $tst_run)
563 {
564 $tst_run->clearQuestions();
565 include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
567 ilObject::_lookupObjId($session->getRefId()),
568 $tst_run->getObjectiveId()
569 );
570 $points = 0;
571 foreach($qst as $id)
572 {
573 $tst_run->addQuestion($id);
575 }
576 $tst_run->setMaxPoints($points);
577 }
578 }
579
581 {
582 include_once './Modules/Course/classes/Objectives/class.ilLORandomTestQuestionPools.php';
583 include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
584
585 foreach($this->run as $tst_run)
586 {
587 // Clear questions of previous run
588 $tst_run->clearQuestions();
590 $this->container_id,
591 $tst_run->getObjectiveId(),
592 ($this->getSettings()->getQualifiedTest() == $session->getRefId() ?
595 );
596 $stored_sequence_id = $rnd->getQplSequence();
597 $points = 0;
598 foreach($seq->getQuestionIds() as $qst)
599 {
600 if($stored_sequence_id == $seq->getResponsibleSourcePoolDefinitionId($qst))
601 {
602 $tst_run->addQuestion($qst);
604 }
605 }
606 $tst_run->setMaxPoints($points);
607 }
608 }
609
610 protected function isInRun($a_qid)
611 {
612 foreach($this->run as $run)
613 {
614 if($run->questionExists($a_qid))
615 {
616 return true;
617 }
618 }
619 return false;
620 }
621
622
623 private static function getQuestionData($testObjId, $questionIds)
624 {
625 global $ilDB, $lng, $ilPluginAdmin;
626
627 require_once 'Modules/TestQuestionPool/classes/class.ilAssQuestionList.php';
628 $questionList = new ilAssQuestionList($ilDB, $lng, $ilPluginAdmin);
629 $questionList->setParentObjId($testObjId);
630
631 $questionList->setQuestionInstanceTypeFilter(ilAssQuestionList::QUESTION_INSTANCE_TYPE_DUPLICATES);
632 $questionList->setQuestionIdsFilter($questionIds);
633
634 $questionList->load();
635
636 return $questionList->getQuestionDataArray();
637 }
638
639 public static function getInstance(ilTestSession $a_test_session)
640 {
641 $adapter = new self(
642 $a_test_session->getUserId(),
643 $a_test_session->getObjectiveOrientedContainerId()
644 );
645
646 $adapter->setTestRefId($a_test_session->getRefId());
647 $adapter->initTestRun($a_test_session);
648
649 return $adapter;
650 }
651}
652?>
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 lookupMaxAttempts($a_container_id, $a_objective_id)
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['PHPCAS_CLIENT']
This global variable is used by the interface class phpCAS.
Definition: CAS.php:276
global $lng
Definition: privfeed.php:40
$results
global $ilDB