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