ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilCourseObjectiveResult.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5define('IL_OBJECTIVE_STATUS_EMPTY','empty');
6define('IL_OBJECTIVE_STATUS_PRETEST','pretest');
7define('IL_OBJECTIVE_STATUS_FINAL','final');
8define('IL_OBJECTIVE_STATUS_NONE','none');
9define('IL_OBJECTIVE_STATUS_FINISHED','finished');
10define('IL_OBJECTIVE_STATUS_PRETEST_NON_SUGGEST','pretest_non_suggest');
11
20{
21 var $db = null;
22 var $user_id = null;
23
24
29 public function __construct($a_usr_id)
30 {
31 global $ilDB;
32
33 $this->db = $ilDB;
34
35 $this->user_id = $a_usr_id;
36 }
37 function getUserId()
38 {
39 return $this->user_id;
40 }
41
42 function getAccomplished($a_crs_id)
43 {
45 }
46 public static function _getAccomplished($a_user_id,$a_crs_id)
47 {
48 global $ilDB;
49
50 include_once 'Modules/Course/classes/class.ilCourseObjective.php';
51 // begin-patch lok
52 $objectives = ilCourseObjective::_getObjectiveIds($a_crs_id,true);
53 // end-patch lok
54
55 if(!is_array($objectives))
56 {
57 return array();
58 }
59 $query = "SELECT objective_id FROM crs_objective_status ".
60 "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
61 "AND user_id = ".$ilDB->quote($a_user_id ,'integer')." ";
62 $res = $ilDB->query($query);
63 while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
64 {
65 $accomplished[] = $row->objective_id;
66 }
67 return $accomplished ? $accomplished : array();
68 }
69
70 function getSuggested($a_crs_id,$a_status = IL_OBJECTIVE_STATUS_FINAL)
71 {
72 return ilCourseObjectiveResult::_getSuggested($this->getUserId(),$a_crs_id,$a_status);
73 }
74
75 public static function _getSuggested($a_user_id,$a_crs_id,$a_status = IL_OBJECTIVE_STATUS_FINAL)
76 {
77 global $ilDB;
78
79 include_once './Modules/Course/classes/class.ilCourseObjective.php';
80 // begin-patch lok
81 $objectives = ilCourseObjective::_getObjectiveIds($a_crs_id,true);
82 // end-patch lok
83
84 $finished = array();
85 if($a_status == IL_OBJECTIVE_STATUS_FINAL or
87 {
88 // check finished
89 $query = "SELECT objective_id FROM crs_objective_status ".
90 "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer')." ".
91 "AND user_id = ".$ilDB->quote($a_user_id ,'integer')." ";
92 $res = $ilDB->query($query);
93 while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
94 {
95 $finished[] = $row->objective_id;
96 }
97 }
98 else
99 {
100 // Pretest
101 $query = "SELECT objective_id FROM crs_objective_status_p ".
102 "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
103 "AND user_id = ".$ilDB->quote($a_user_id ,'integer');
104 $res = $ilDB->query($query);
105 while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
106 {
107 $finished[] = $row->objective_id;
108 }
109 }
110 foreach($objectives as $objective_id)
111 {
112 if(!in_array($objective_id,$finished))
113 {
114 $suggested[] = $objective_id;
115 }
116 }
117 return $suggested ? $suggested : array();
118 }
119
126 public static function getSuggestedQuestions($a_usr_id,$a_crs_id)
127 {
128 foreach(self::_getSuggested($a_usr_id,$a_crs_id) as $objective_id)
129 {
130 include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
131 $obj = new ilCourseObjectiveQuestion($objective_id);
132 foreach($obj->getFinalTestQuestions() as $qst)
133 {
134 $qsts[] = $qst['question_id'];
135 }
136 }
137 return $qsts ? $qsts : array();
138 }
139
140 protected function resetTestForUser(ilObjTest $a_test, $a_user_id)
141 {
142 // this is done in ilTestLP (see below)
143 // $a_test->removeTestResultsForUser($a_user_id);
144
145 // #15038
146 include_once "Modules/Test/classes/class.ilTestLP.php";
147 $test_lp = ilTestLP::getInstance($a_test->getId());
148 $test_lp->resetLPDataForUserIds(array($a_user_id));
149
150 // #15205 - see ilObjTestGUI::confirmDeleteSelectedUserDataObject()
151 $active_id = $a_test->getActiveIdOfUser($a_user_id);
152 if($active_id)
153 {
154 $a_test->removeTestActives(array($active_id));
155 }
156 }
157
158 function reset($a_course_id)
159 {
160 global $ilDB;
161
162 include_once './Modules/Course/classes/class.ilCourseObjective.php';
163 include_once './Modules/Course/classes/class.ilCourseObjectiveQuestion.php';
164
165 include_once './Services/Object/classes/class.ilObjectFactory.php';
166 $factory = new ilObjectFactory();
167
168 include_once './Modules/Course/classes/Objectives/class.ilLOTestAssignments.php';
169 include_once './Modules/Course/classes/Objectives/class.ilLOSettings.php';
170 $assignments = ilLOTestAssignments::getInstance($a_course_id);
171 foreach(array_merge
172 (
173 $assignments->getAssignmentsByType(ilLOSettings::TYPE_TEST_INITIAL),
174 $assignments->getAssignmentsByType(ilLOSettings::TYPE_TEST_QUALIFIED)
175 )
176 as $assignment)
177 {
178 $tst = $factory->getInstanceByRefId($assignment->getTestRefId(),FALSE);
179 if($tst instanceof ilObjTest)
180 {
181 global $lng;
182
183 require_once 'Modules/Test/classes/class.ilTestParticipantData.php';
184 $participantData = new ilTestParticipantData($ilDB, $lng);
185 $participantData->setUserIds(array($this->getUserId()));
186 $participantData->load($tst->getTestId());
187 $tst->removeTestResults($participantData);
188
189 }
190 }
191
192 $initial = ilLOSettings::getInstanceByObjId($a_course_id)->getInitialTest();
193 $initial_tst = $factory->getInstanceByRefId($initial, FALSE);
194 if($initial_tst instanceof ilObjTest)
195 {
196 $this->resetTestForUser($initial_tst, $this->getUserId());
197 }
198
199 $qualified = ilLOSettings::getInstanceByObjId($a_course_id)->getQualifiedTest();
200 $qualified_tst = $factory->getInstanceByRefId($qualified, FALSE);
201 if($qualified_tst instanceof ilObjTest)
202 {
203 $this->resetTestForUser($qualified_tst, $this->getUserId());
204 }
205
206 $objectives = ilCourseObjective::_getObjectiveIds($a_course_id,FALSE);
207
208 if(count($objectives))
209 {
210 $query = "DELETE FROM crs_objective_status ".
211 "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
212 "AND user_id = ".$ilDB->quote($this->getUserId() ,'integer')." ";
213 $res = $ilDB->manipulate($query);
214
215 $query = "DELETE FROM crs_objective_status_p ".
216 "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
217 "AND user_id = ".$ilDB->quote($this->getUserId())."";
218 $res = $ilDB->manipulate($query);
219
220 $query = "DELETE FROM loc_user_results ".
221 "WHERE ".$ilDB->in('objective_id',$objectives,false,'integer').' '.
222 "AND user_id = ".$ilDB->quote($this->getUserId())."";
223 }
224
225 // update/reset LP for course
226 include_once './Services/Tracking/classes/class.ilLPStatusWrapper.php';
227 ilLPStatusWrapper::_updateStatus($a_course_id, $this->getUserId());
228
229 return true;
230 }
231
232 function getStatus($a_course_id)
233 {
234 include_once './Modules/TestQuestionPool/classes/class.assQuestion.php';
235 include_once 'Modules/Course/classes/class.ilCourseObjective.php';
236 // begin-patch lok
237 $objective_ids = ilCourseObjective::_getObjectiveIds($a_course_id,true);
238 // end-patch lok
239 $objectives = ilCourseObjectiveResult::_readAssignedObjectives($objective_ids);
240 $accomplished = $this->getAccomplished($a_course_id);
241 $suggested = $this->getSuggested($a_course_id);
242
243 if(!count($objective_ids))
244 {
246 }
247
248 if(count($accomplished) == count($objective_ids))
249 {
251 }
252
253 $all_pretest_answered = false;
254 $all_final_answered = false;
255 foreach($objectives as $data)
256 {
257 if(assQuestion::_areAnswered($this->getUserId(),$data['questions']))
258 {
259 if($data['tst_status'])
260 {
261 $all_final_answered = true;
262 }
263 else
264 {
265 $all_pretest_answered = true;
266 }
267 }
268 }
269 if($all_final_answered)
270 {
272 }
273 if($all_pretest_answered and
274 !count($suggested))
275 {
277 }
278 elseif($all_pretest_answered)
279 {
281 }
283 }
284
285 function hasAccomplishedObjective($a_objective_id)
286 {
287 global $ilDB;
288
289 $query = "SELECT status FROM crs_objective_status ".
290 "WHERE objective_id = ".$ilDB->quote($a_objective_id ,'integer')." ".
291 "AND user_id = ".$ilDB->quote($this->getUserId() ,'integer')."";
292
293 $res = $this->db->query($query);
294 while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
295 {
296 return true;
297 }
298 return false;
299 }
300
301 function readStatus($a_crs_id)
302 {
303 include_once './Modules/Course/classes/class.ilCourseObjective.php';
304
305 // begin-patch lok
306 $objective_ids = ilCourseObjective::_getObjectiveIds($a_crs_id,true);
307 // end-patch lok
308 $objectives = ilCourseObjectiveResult::_readAssignedObjectives($objective_ids);
310 return true;
311 }
312
313
314
315
316 // PRIVATE
317 function __deleteEntries($a_objective_ids)
318 {
319 global $ilLog;
320
321 $ilLog->logStack();
322 #$ilLog(__METHOD__.': Call of deprecated method.');
323
324 return true;
325 }
326
327 public static function _deleteUser($user_id)
328 {
329 global $ilDB;
330
331 $query = "DELETE FROM crs_objective_status ".
332 "WHERE user_id = ".$ilDB->quote($user_id ,'integer')." ";
333 $res = $ilDB->manipulate($query);
334
335 $query = "DELETE FROM crs_objective_status_p ".
336 "WHERE user_id = ".$ilDB->quote($user_id ,'integer')." ";
337 $res = $ilDB->manipulate($query);
338 return true;
339 }
340
341 public static function _updateObjectiveResult($a_user_id,$a_active_id,$a_question_id)
342 {
343 // find all objectives this question is assigned to
344 if(!$objectives = self::_readAssignedObjectivesOfQuestion($a_question_id))
345 {
346 // no objectives found. TODO user has passed a test. After that questions of that test are assigned to an objective.
347 // => User has not passed
348 return true;
349 }
350 self::_updateObjectiveStatus($a_user_id,$objectives);
351
352 return true;
353 }
354
355 public static function _readAssignedObjectivesOfQuestion($a_question_id)
356 {
357 global $ilDB;
358
359 // get all objtives and questions this current question is assigned to
360 $query = "SELECT q2.question_id qid,q2.objective_id ob FROM crs_objective_qst q1, ".
361 "crs_objective_qst q2 ".
362 "WHERE q1.question_id = ".$ilDB->quote($a_question_id ,'integer')." ".
363 "AND q1.objective_id = q2.objective_id ";
364
365 $res = $ilDB->query($query);
366 while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
367 {
368 $objectives['all_objectives'][$row->ob] = $row->ob;
369 $objectives['all_questions'][$row->qid] = $row->qid;
370 }
371 if(!is_array($objectives))
372 {
373 return false;
374 }
375 $objectives['objectives'] = self::_readAssignedObjectives($objectives['all_objectives']);
376 return $objectives ? $objectives : array();
377 }
378
379
380 public static function _readAssignedObjectives($a_all_objectives)
381 {
382 global $ilDB;
383
384 // Read necessary points
385 $query = "SELECT t.objective_id obj,t.ref_id ref, question_id,tst_status,tst_limit ".
386 "FROM crs_objective_tst t JOIN crs_objective_qst q ".
387 "ON (t.objective_id = q.objective_id AND t.ref_id = q.ref_id) ".
388 "WHERE ".$ilDB->in('t.objective_id',$a_all_objectives,false,'integer');
389
390 $res = $ilDB->query($query);
391 while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
392 {
393 /*
394 $objectives[$row->obj."_".$row->ref]['questions'][$row->question_id] = $row->question_id;
395 $objectives[$row->obj."_".$row->ref]['tst_status'] = $row->tst_status;
396 $objectives[$row->obj."_".$row->ref]['tst_limit'] = $row->tst_limit;
397 $objectives[$row->obj."_".$row->ref]['objective_id'] = $row->obj;
398 */
399
400 $objectives[$row->obj."_".$row->tst_status]['questions'][$row->question_id] = $row->question_id;
401 $objectives[$row->obj."_".$row->tst_status]['tst_status'] = $row->tst_status;
402 $objectives[$row->obj."_".$row->tst_status]['tst_limit'] = $row->tst_limit;
403 $objectives[$row->obj."_".$row->tst_status]['objective_id'] = $row->obj;
404
405
406 }
407 return $objectives ? $objectives : array();
408 }
409
410 static function _updateObjectiveStatus($a_user_id,$objectives)
411 {
412 global $ilDB,$ilUser;
413
414 if(!count($objectives['all_questions']) or
415 !count($objectives['all_objectives']))
416 {
417 return false;
418 }
419 // Read reachable points
420 $query = "SELECT question_id,points FROM qpl_questions ".
421 "WHERE ".$ilDB->in('question_id',(array) $objectives['all_questions'],false,'integer');
422 $res = $ilDB->query($query);
423 while($row = $ilDB->fetchAssoc($res))
424 {
425 $objectives['all_question_points'][$row['question_id']]['max_points'] = $row['points'];
426 }
427 // Read reached points
428 $query = "SELECT question_fi, MAX(points) as reached FROM tst_test_result ".
429 "JOIN tst_active ON (active_id = active_fi) ".
430 "WHERE user_fi = ".$ilDB->quote($a_user_id,'integer')." ".
431 "AND ".$ilDB->in('question_fi',(array) $objectives['all_questions'],false,'integer')." ".
432 #"AND question_fi IN (".implode(",",ilUtil::quoteArray($objectives['all_questions'])).") ".
433 "GROUP BY question_fi,user_fi";
434 $res = $ilDB->query($query);
435 while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
436 {
437 $objectives['all_question_points'][$row->question_fi]['reached_points'] = $row->reached;
438 }
439
440 // Check accomplished
441 $fullfilled = array();
442 $pretest = array();
443 foreach($objectives['objectives'] as $kind => $data)
444 {
445 // objective does not allow to change status
446 if(ilCourseObjectiveResult::__isFullfilled($objectives['all_question_points'],$data))
447 {
448 // Status 0 means pretest fullfilled, status 1 means final test fullfilled
449 if($data['tst_status'])
450 {
451 $fullfilled[] = array($data['objective_id'],$ilUser->getId(),$data['tst_status']);
452 }
453 else
454 {
455 $pretest[] = array($data['objective_id'],$ilUser->getId());
456 }
457 }
458 }
459 if(count($fullfilled))
460 {
461 foreach($fullfilled as $fullfilled_arr)
462 {
463 $ilDB->replace(
464 'crs_objective_status',
465 array(
466 'objective_id' => array('integer',$fullfilled_arr[0]),
467 'user_id' => array('integer',$fullfilled_arr[1])
468 ),
469 array(
470 'status' => array('integer',$fullfilled_arr[2])
471 )
472 );
473 }
474 ilCourseObjectiveResult::__updatePassed($a_user_id,$objectives['all_objectives']);
475 }
476 if(count($pretest))
477 {
478 foreach($pretest as $pretest_arr)
479 {
480 $ilDB->replace(
481 'crs_objective_status_p',
482 array(
483 'objective_id' => array('integer',$pretest_arr[0]),
484 'user_id' => array('integer',$pretest_arr[1])
485 ),
486 array()
487 );
488 }
489 }
490 return true;
491 }
492
493 public static function __isFullfilled($question_points,$objective_data)
494 {
495 if(!is_array($objective_data['questions']))
496 {
497 return false;
498 }
499 $max_points = 0;
500 $reached_points = 0;
501 foreach($objective_data['questions'] as $question_id)
502 {
503 $max_points += $question_points[$question_id]['max_points'];
504 $reached_points += $question_points[$question_id]['reached_points'];
505 }
506 if(!$max_points)
507 {
508 return false;
509 }
510
511 return $reached_points >= $objective_data['tst_limit'] ? true : false;
512
513 return (($reached_points / $max_points * 100) >= $objective_data['tst_limit']) ? true : false;
514 }
515
523 static function __updatePassed($a_user_id,$objective_ids)
524 {
525 global $ilDB;
526
527 $passed = array();
528
529 $query = "SELECT COUNT(t1.crs_id) num,t1.crs_id FROM crs_objectives t1 ".
530 "JOIN crs_objectives t2 WHERE t1.crs_id = t2.crs_id and ".
531 $ilDB->in('t1.objective_id',$objective_ids,false,'integer')." ".
532 "GROUP BY t1.crs_id";
533 $res = $ilDB->query($query);
534 $crs_ids = array();
535 while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
536 {
537 $query = "SELECT COUNT(cs.objective_id) num_passed FROM crs_objective_status cs ".
538 "JOIN crs_objectives co ON cs.objective_id = co.objective_id ".
539 "WHERE crs_id = ".$ilDB->quote($row->crs_id ,'integer')." ".
540 "AND user_id = ".$ilDB->quote($a_user_id ,'integer')." ";
541
542 $user_res = $ilDB->query($query);
543 while($user_row = $user_res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
544 {
545 if($user_row->num_passed == $row->num)
546 {
547 $passed[] = $row->crs_id;
548 }
549 }
550 $crs_ids[$row->crs_id] = $row->crs_id;
551 }
552 if(count($passed))
553 {
554 foreach($passed as $crs_id)
555 {
556 include_once('Modules/Course/classes/class.ilCourseParticipants.php');
558 $members->updatePassed($a_user_id,true);
559 }
560 }
561
562 // update tracking status
563 foreach ($crs_ids as $cid)
564 {
565 include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
566 ilLPStatusWrapper::_updateStatus($cid, $a_user_id);
567 }
568 }
569
570}
571?>
An exception for terminatinating execution or to throw for unit testing.
const IL_OBJECTIVE_STATUS_PRETEST_NON_SUGGEST
const IL_OBJECTIVE_STATUS_EMPTY
const IL_OBJECTIVE_STATUS_FINISHED
const IL_OBJECTIVE_STATUS_NONE
const IL_OBJECTIVE_STATUS_PRETEST
const IL_OBJECTIVE_STATUS_FINAL
static _areAnswered($a_user_id, $a_question_ids)
Checks if an array of question ids is answered by an user or not.
class ilcourseobjectiveQuestion
static _readAssignedObjectives($a_all_objectives)
static _getSuggested($a_user_id, $a_crs_id, $a_status=IL_OBJECTIVE_STATUS_FINAL)
static _updateObjectiveResult($a_user_id, $a_active_id, $a_question_id)
static _readAssignedObjectivesOfQuestion($a_question_id)
static getSuggestedQuestions($a_usr_id, $a_crs_id)
get suggested questions ids
static _updateObjectiveStatus($a_user_id, $objectives)
static _getAccomplished($a_user_id, $a_crs_id)
resetTestForUser(ilObjTest $a_test, $a_user_id)
static __isFullfilled($question_points, $objective_data)
static __updatePassed($a_user_id, $objective_ids)
can be protected?
getSuggested($a_crs_id, $a_status=IL_OBJECTIVE_STATUS_FINAL)
static _getObjectiveIds($course_id, $a_activated_only=false)
static _getInstanceByObjId($a_obj_id)
Get singleton instance.
static getInstanceByObjId($a_obj_id)
get singleton instance
static getInstance($a_container_id)
Get instance by container id.
static _updateStatus($a_obj_id, $a_usr_id, $a_obj=null, $a_percentage=false, $a_force_raise=false)
Update status.
removeTestActives($activeIds)
getActiveIdOfUser($user_id="", $anonymous_id="")
Gets the active id of a given user.
Class ilObjectFactory.
static getInstance($a_obj_id)
getId()
get object id @access public
global $lng
Definition: privfeed.php:17
global $ilDB
$ilUser
Definition: imgupload.php:18